Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Functions | Variables

pg_dump.c File Reference

#include "postgres_fe.h"
#include <unistd.h>
#include <ctype.h>
#include "getopt_long.h"
#include "access/attnum.h"
#include "access/sysattr.h"
#include "access/transam.h"
#include "catalog/pg_cast.h"
#include "catalog/pg_class.h"
#include "catalog/pg_default_acl.h"
#include "catalog/pg_event_trigger.h"
#include "catalog/pg_largeobject.h"
#include "catalog/pg_largeobject_metadata.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_type.h"
#include "libpq/libpq-fs.h"
#include "pg_backup_archiver.h"
#include "pg_backup_db.h"
#include "pg_backup_utils.h"
#include "dumputils.h"
#include "parallel.h"
Include dependency graph for pg_dump.c:

Go to the source code of this file.

Data Structures

struct  CommentItem
struct  SecLabelItem

Functions

static void help (const char *progname)
static void setup_connection (Archive *AH, const char *dumpencoding, char *use_role)
static ArchiveFormat parseArchiveFormat (const char *format, ArchiveMode *mode)
static void expand_schema_name_patterns (Archive *fout, SimpleStringList *patterns, SimpleOidList *oids)
static void expand_table_name_patterns (Archive *fout, SimpleStringList *patterns, SimpleOidList *oids)
static NamespaceInfofindNamespace (Archive *fout, Oid nsoid, Oid objoid)
static void dumpTableData (Archive *fout, TableDataInfo *tdinfo)
static void refreshMatViewData (Archive *fout, TableDataInfo *tdinfo)
static void guessConstraintInheritance (TableInfo *tblinfo, int numTables)
static void dumpComment (Archive *fout, const char *target, const char *namespace, const char *owner, CatalogId catalogId, int subid, DumpId dumpId)
static int findComments (Archive *fout, Oid classoid, Oid objoid, CommentItem **items)
static int collectComments (Archive *fout, CommentItem **items)
static void dumpSecLabel (Archive *fout, const char *target, const char *namespace, const char *owner, CatalogId catalogId, int subid, DumpId dumpId)
static int findSecLabels (Archive *fout, Oid classoid, Oid objoid, SecLabelItem **items)
static int collectSecLabels (Archive *fout, SecLabelItem **items)
static void dumpDumpableObject (Archive *fout, DumpableObject *dobj)
static void dumpNamespace (Archive *fout, NamespaceInfo *nspinfo)
static void dumpExtension (Archive *fout, ExtensionInfo *extinfo)
static void dumpType (Archive *fout, TypeInfo *tyinfo)
static void dumpBaseType (Archive *fout, TypeInfo *tyinfo)
static void dumpEnumType (Archive *fout, TypeInfo *tyinfo)
static void dumpRangeType (Archive *fout, TypeInfo *tyinfo)
static void dumpDomain (Archive *fout, TypeInfo *tyinfo)
static void dumpCompositeType (Archive *fout, TypeInfo *tyinfo)
static void dumpCompositeTypeColComments (Archive *fout, TypeInfo *tyinfo)
static void dumpShellType (Archive *fout, ShellTypeInfo *stinfo)
static void dumpProcLang (Archive *fout, ProcLangInfo *plang)
static void dumpFunc (Archive *fout, FuncInfo *finfo)
static void dumpCast (Archive *fout, CastInfo *cast)
static void dumpOpr (Archive *fout, OprInfo *oprinfo)
static void dumpOpclass (Archive *fout, OpclassInfo *opcinfo)
static void dumpOpfamily (Archive *fout, OpfamilyInfo *opfinfo)
static void dumpCollation (Archive *fout, CollInfo *convinfo)
static void dumpConversion (Archive *fout, ConvInfo *convinfo)
static void dumpRule (Archive *fout, RuleInfo *rinfo)
static void dumpAgg (Archive *fout, AggInfo *agginfo)
static void dumpTrigger (Archive *fout, TriggerInfo *tginfo)
static void dumpEventTrigger (Archive *fout, EventTriggerInfo *evtinfo)
static void dumpTable (Archive *fout, TableInfo *tbinfo)
static void dumpTableSchema (Archive *fout, TableInfo *tbinfo)
static void dumpAttrDef (Archive *fout, AttrDefInfo *adinfo)
static void dumpSequence (Archive *fout, TableInfo *tbinfo)
static void dumpSequenceData (Archive *fout, TableDataInfo *tdinfo)
static void dumpIndex (Archive *fout, IndxInfo *indxinfo)
static void dumpConstraint (Archive *fout, ConstraintInfo *coninfo)
static void dumpTableConstraintComment (Archive *fout, ConstraintInfo *coninfo)
static void dumpTSParser (Archive *fout, TSParserInfo *prsinfo)
static void dumpTSDictionary (Archive *fout, TSDictInfo *dictinfo)
static void dumpTSTemplate (Archive *fout, TSTemplateInfo *tmplinfo)
static void dumpTSConfig (Archive *fout, TSConfigInfo *cfginfo)
static void dumpForeignDataWrapper (Archive *fout, FdwInfo *fdwinfo)
static void dumpForeignServer (Archive *fout, ForeignServerInfo *srvinfo)
static void dumpUserMappings (Archive *fout, const char *servername, const char *namespace, const char *owner, CatalogId catalogId, DumpId dumpId)
static void dumpDefaultACL (Archive *fout, DefaultACLInfo *daclinfo)
static void dumpACL (Archive *fout, CatalogId objCatId, DumpId objDumpId, const char *type, const char *name, const char *subname, const char *tag, const char *nspname, const char *owner, const char *acls)
static void getDependencies (Archive *fout)
static void BuildArchiveDependencies (Archive *fout)
static void findDumpableDependencies (ArchiveHandle *AH, DumpableObject *dobj, DumpId **dependencies, int *nDeps, int *allocDeps)
static DumpableObjectcreateBoundaryObjects (void)
static void addBoundaryDependencies (DumpableObject **dobjs, int numObjs, DumpableObject *boundaryObjs)
static void getDomainConstraints (Archive *fout, TypeInfo *tyinfo)
static void getTableData (TableInfo *tblinfo, int numTables, bool oids)
static void makeTableDataInfo (TableInfo *tbinfo, bool oids)
static void buildMatViewRefreshDependencies (Archive *fout)
static void getTableDataFKConstraints (void)
static char * format_function_arguments (FuncInfo *finfo, char *funcargs)
static char * format_function_arguments_old (Archive *fout, FuncInfo *finfo, int nallargs, char **allargtypes, char **argmodes, char **argnames)
static char * format_function_signature (Archive *fout, FuncInfo *finfo, bool honor_quotes)
static const char * convertRegProcReference (Archive *fout, const char *proc)
static const char * convertOperatorReference (Archive *fout, const char *opr)
static const char * convertTSFunction (Archive *fout, Oid funcOid)
static Oid findLastBuiltinOid_V71 (Archive *fout, const char *)
static Oid findLastBuiltinOid_V70 (Archive *fout)
static void selectSourceSchema (Archive *fout, const char *schemaName)
static char * getFormattedTypeName (Archive *fout, Oid oid, OidOptions opts)
static char * myFormatType (const char *typname, int32 typmod)
static void getBlobs (Archive *fout)
static void dumpBlob (Archive *fout, BlobInfo *binfo)
static int dumpBlobs (Archive *fout, void *arg)
static void dumpDatabase (Archive *AH)
static void dumpEncoding (Archive *AH)
static void dumpStdStrings (Archive *AH)
static void binary_upgrade_set_type_oids_by_type_oid (Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_type_oid)
static bool binary_upgrade_set_type_oids_by_rel_oid (Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_rel_oid)
static void binary_upgrade_set_pg_class_oids (Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_class_oid, bool is_index)
static void binary_upgrade_extension_member (PQExpBuffer upgrade_buffer, DumpableObject *dobj, const char *objlabel)
static const char * getAttrName (int attrnum, TableInfo *tblInfo)
static const char * fmtCopyColumnList (const TableInfo *ti, PQExpBuffer buffer)
static char * get_synchronized_snapshot (Archive *fout)
static PGresultExecuteSqlQueryForSingleRow (Archive *fout, char *query)
static void setupDumpWorker (Archive *AHX, RestoreOptions *ropt)
int main (int argc, char **argv)
static void selectDumpableNamespace (NamespaceInfo *nsinfo)
static void selectDumpableTable (TableInfo *tbinfo)
static void selectDumpableType (TypeInfo *tyinfo)
static void selectDumpableDefaultACL (DefaultACLInfo *dinfo)
static void selectDumpableExtension (ExtensionInfo *extinfo)
static void selectDumpableObject (DumpableObject *dobj)
static int dumpTableData_copy (Archive *fout, void *dcontext)
static int dumpTableData_insert (Archive *fout, void *dcontext)
NamespaceInfogetNamespaces (Archive *fout, int *numNamespaces)
ExtensionInfogetExtensions (Archive *fout, int *numExtensions)
TypeInfogetTypes (Archive *fout, int *numTypes)
OprInfogetOperators (Archive *fout, int *numOprs)
CollInfogetCollations (Archive *fout, int *numCollations)
ConvInfogetConversions (Archive *fout, int *numConversions)
OpclassInfogetOpclasses (Archive *fout, int *numOpclasses)
OpfamilyInfogetOpfamilies (Archive *fout, int *numOpfamilies)
AggInfogetAggregates (Archive *fout, int *numAggs)
FuncInfogetFuncs (Archive *fout, int *numFuncs)
TableInfogetTables (Archive *fout, int *numTables)
void getOwnedSeqs (Archive *fout, TableInfo tblinfo[], int numTables)
InhInfogetInherits (Archive *fout, int *numInherits)
void getIndexes (Archive *fout, TableInfo tblinfo[], int numTables)
void getConstraints (Archive *fout, TableInfo tblinfo[], int numTables)
RuleInfogetRules (Archive *fout, int *numRules)
void getTriggers (Archive *fout, TableInfo tblinfo[], int numTables)
EventTriggerInfogetEventTriggers (Archive *fout, int *numEventTriggers)
ProcLangInfogetProcLangs (Archive *fout, int *numProcLangs)
CastInfogetCasts (Archive *fout, int *numCasts)
void getTableAttrs (Archive *fout, TableInfo *tblinfo, int numTables)
bool shouldPrintColumn (TableInfo *tbinfo, int colno)
TSParserInfogetTSParsers (Archive *fout, int *numTSParsers)
TSDictInfogetTSDictionaries (Archive *fout, int *numTSDicts)
TSTemplateInfogetTSTemplates (Archive *fout, int *numTSTemplates)
TSConfigInfogetTSConfigurations (Archive *fout, int *numTSConfigs)
FdwInfogetForeignDataWrappers (Archive *fout, int *numForeignDataWrappers)
ForeignServerInfogetForeignServers (Archive *fout, int *numForeignServers)
DefaultACLInfogetDefaultACLs (Archive *fout, int *numDefaultACLs)
static void dumpTableComment (Archive *fout, TableInfo *tbinfo, const char *reltypename)
static bool shouldDumpProcLangs (void)
static char * format_aggregate_signature (AggInfo *agginfo, Archive *fout, bool honor_quotes)
static void dumpTableSecLabel (Archive *fout, TableInfo *tbinfo, const char *reltypename)
static PQExpBuffer createViewAsClause (Archive *fout, TableInfo *tbinfo)
void getExtensionMembership (Archive *fout, ExtensionInfo extinfo[], int numExtensions)

Variables

char * optarg
int optind
int opterr
bool g_verbose
bool schemaOnly
bool dataOnly
int dumpSections
bool aclsSkip
const char * lockWaitTimeout
static const char * username_subquery
static Oid g_last_builtin_oid
static SimpleStringList schema_include_patterns = {NULL, NULL}
static SimpleOidList schema_include_oids = {NULL, NULL}
static SimpleStringList schema_exclude_patterns = {NULL, NULL}
static SimpleOidList schema_exclude_oids = {NULL, NULL}
static SimpleStringList table_include_patterns = {NULL, NULL}
static SimpleOidList table_include_oids = {NULL, NULL}
static SimpleStringList table_exclude_patterns = {NULL, NULL}
static SimpleOidList table_exclude_oids = {NULL, NULL}
static SimpleStringList tabledata_exclude_patterns = {NULL, NULL}
static SimpleOidList tabledata_exclude_oids = {NULL, NULL}
static bool include_everything = true
char g_opaque_type [10]
char g_comment_start [10]
char g_comment_end [10]
static const CatalogId nilCatalogId = {0, 0}
static int binary_upgrade = 0
static int disable_dollar_quoting = 0
static int dump_inserts = 0
static int column_inserts = 0
static int no_security_labels = 0
static int no_synchronized_snapshots = 0
static int no_unlogged_table_data = 0
static int serializable_deferrable = 0

Function Documentation

static void addBoundaryDependencies ( DumpableObject **  dobjs,
int  numObjs,
DumpableObject boundaryObjs 
) [static]

Definition at line 14842 of file pg_dump.c.

References addObjectDependency(), DO_AGG, DO_ATTRDEF, DO_BLOB, DO_BLOB_DATA, DO_CAST, DO_COLLATION, DO_CONSTRAINT, DO_CONVERSION, DO_DEFAULT_ACL, DO_DUMMY_TYPE, DO_EVENT_TRIGGER, DO_EXTENSION, DO_FDW, DO_FK_CONSTRAINT, DO_FOREIGN_SERVER, DO_FUNC, DO_INDEX, DO_NAMESPACE, DO_OPCLASS, DO_OPERATOR, DO_OPFAMILY, DO_POST_DATA_BOUNDARY, DO_PRE_DATA_BOUNDARY, DO_PROCLANG, DO_REFRESH_MATVIEW, DO_RULE, DO_SHELL_TYPE, DO_TABLE, DO_TABLE_DATA, DO_TRIGGER, DO_TSCONFIG, DO_TSDICT, DO_TSPARSER, DO_TSTEMPLATE, DO_TYPE, _dumpableObject::dumpId, i, and _dumpableObject::objType.

Referenced by main().

{
    DumpableObject *preDataBound = boundaryObjs + 0;
    DumpableObject *postDataBound = boundaryObjs + 1;
    int         i;

    for (i = 0; i < numObjs; i++)
    {
        DumpableObject *dobj = dobjs[i];

        /*
         * The classification of object types here must match the SECTION_xxx
         * values assigned during subsequent ArchiveEntry calls!
         */
        switch (dobj->objType)
        {
            case DO_NAMESPACE:
            case DO_EXTENSION:
            case DO_TYPE:
            case DO_SHELL_TYPE:
            case DO_FUNC:
            case DO_AGG:
            case DO_OPERATOR:
            case DO_OPCLASS:
            case DO_OPFAMILY:
            case DO_COLLATION:
            case DO_CONVERSION:
            case DO_TABLE:
            case DO_ATTRDEF:
            case DO_PROCLANG:
            case DO_CAST:
            case DO_DUMMY_TYPE:
            case DO_TSPARSER:
            case DO_TSDICT:
            case DO_TSTEMPLATE:
            case DO_TSCONFIG:
            case DO_FDW:
            case DO_FOREIGN_SERVER:
            case DO_BLOB:
                /* Pre-data objects: must come before the pre-data boundary */
                addObjectDependency(preDataBound, dobj->dumpId);
                break;
            case DO_TABLE_DATA:
            case DO_BLOB_DATA:
                /* Data objects: must come between the boundaries */
                addObjectDependency(dobj, preDataBound->dumpId);
                addObjectDependency(postDataBound, dobj->dumpId);
                break;
            case DO_INDEX:
            case DO_REFRESH_MATVIEW:
            case DO_TRIGGER:
            case DO_EVENT_TRIGGER:
            case DO_DEFAULT_ACL:
                /* Post-data objects: must come after the post-data boundary */
                addObjectDependency(dobj, postDataBound->dumpId);
                break;
            case DO_RULE:
                /* Rules are post-data, but only if dumped separately */
                if (((RuleInfo *) dobj)->separate)
                    addObjectDependency(dobj, postDataBound->dumpId);
                break;
            case DO_CONSTRAINT:
            case DO_FK_CONSTRAINT:
                /* Constraints are post-data, but only if dumped separately */
                if (((ConstraintInfo *) dobj)->separate)
                    addObjectDependency(dobj, postDataBound->dumpId);
                break;
            case DO_PRE_DATA_BOUNDARY:
                /* nothing to do */
                break;
            case DO_POST_DATA_BOUNDARY:
                /* must come after the pre-data boundary */
                addObjectDependency(dobj, preDataBound->dumpId);
                break;
        }
    }
}

static void binary_upgrade_extension_member ( PQExpBuffer  upgrade_buffer,
DumpableObject dobj,
const char *  objlabel 
) [static]

Definition at line 2840 of file pg_dump.c.

References appendPQExpBuffer(), _dumpableObject::dependencies, DO_EXTENSION, exit_horribly(), _dumpableObject::ext_member, findObjectByDumpId(), fmtId(), i, _dumpableObject::name, _dumpableObject::nDeps, NULL, and _dumpableObject::objType.

Referenced by dumpAgg(), dumpBaseType(), dumpCast(), dumpCollation(), dumpCompositeType(), dumpConversion(), dumpDomain(), dumpEnumType(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpNamespace(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpProcLang(), dumpRangeType(), dumpSequence(), dumpTableSchema(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), and dumpTSTemplate().

{
    DumpableObject *extobj = NULL;
    int         i;

    if (!dobj->ext_member)
        return;

    /*
     * Find the parent extension.  We could avoid this search if we wanted to
     * add a link field to DumpableObject, but the space costs of that would
     * be considerable.  We assume that member objects could only have a
     * direct dependency on their own extension, not any others.
     */
    for (i = 0; i < dobj->nDeps; i++)
    {
        extobj = findObjectByDumpId(dobj->dependencies[i]);
        if (extobj && extobj->objType == DO_EXTENSION)
            break;
        extobj = NULL;
    }
    if (extobj == NULL)
        exit_horribly(NULL, "could not find parent extension for %s\n", objlabel);

    appendPQExpBuffer(upgrade_buffer,
      "\n-- For binary upgrade, handle extension membership the hard way\n");
    appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s;\n",
                      fmtId(extobj->name),
                      objlabel);
}

static void binary_upgrade_set_pg_class_oids ( Archive fout,
PQExpBuffer  upgrade_buffer,
Oid  pg_class_oid,
bool  is_index 
) [static]

Definition at line 2773 of file pg_dump.c.

References appendPQExpBuffer(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQueryForSingleRow(), OidIsValid, PQclear(), PQfnumber(), and PQgetvalue().

Referenced by dumpCompositeType(), dumpConstraint(), dumpIndex(), dumpSequence(), and dumpTableSchema().

{
    PQExpBuffer upgrade_query = createPQExpBuffer();
    PGresult   *upgrade_res;
    Oid         pg_class_reltoastrelid;
    Oid         pg_class_reltoastidxid;

    appendPQExpBuffer(upgrade_query,
                      "SELECT c.reltoastrelid, t.reltoastidxid "
                      "FROM pg_catalog.pg_class c LEFT JOIN "
                      "pg_catalog.pg_class t ON (c.reltoastrelid = t.oid) "
                      "WHERE c.oid = '%u'::pg_catalog.oid;",
                      pg_class_oid);

    upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);

    pg_class_reltoastrelid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "reltoastrelid")));
    pg_class_reltoastidxid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "reltoastidxid")));

    appendPQExpBuffer(upgrade_buffer,
                   "\n-- For binary upgrade, must preserve pg_class oids\n");

    if (!is_index)
    {
        appendPQExpBuffer(upgrade_buffer,
                          "SELECT binary_upgrade.set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
                          pg_class_oid);
        /* only tables have toast tables, not indexes */
        if (OidIsValid(pg_class_reltoastrelid))
        {
            /*
             * One complexity is that the table definition might not require
             * the creation of a TOAST table, and the TOAST table might have
             * been created long after table creation, when the table was
             * loaded with wide data.  By setting the TOAST oid we force
             * creation of the TOAST heap and TOAST index by the backend so we
             * can cleanly copy the files during binary upgrade.
             */

            appendPQExpBuffer(upgrade_buffer,
                              "SELECT binary_upgrade.set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
                              pg_class_reltoastrelid);

            /* every toast table has an index */
            appendPQExpBuffer(upgrade_buffer,
                              "SELECT binary_upgrade.set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
                              pg_class_reltoastidxid);
        }
    }
    else
        appendPQExpBuffer(upgrade_buffer,
                          "SELECT binary_upgrade.set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
                          pg_class_oid);

    appendPQExpBuffer(upgrade_buffer, "\n");

    PQclear(upgrade_res);
    destroyPQExpBuffer(upgrade_query);
}

static bool binary_upgrade_set_type_oids_by_rel_oid ( Archive fout,
PQExpBuffer  upgrade_buffer,
Oid  pg_rel_oid 
) [static]

Definition at line 2727 of file pg_dump.c.

References appendPQExpBuffer(), atooid, binary_upgrade_set_type_oids_by_type_oid(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQueryForSingleRow(), PQclear(), PQfnumber(), PQgetisnull(), and PQgetvalue().

Referenced by dumpSequence(), and dumpTableSchema().

{
    PQExpBuffer upgrade_query = createPQExpBuffer();
    PGresult   *upgrade_res;
    Oid         pg_type_oid;
    bool        toast_set = false;

    /* we only support old >= 8.3 for binary upgrades */
    appendPQExpBuffer(upgrade_query,
                      "SELECT c.reltype AS crel, t.reltype AS trel "
                      "FROM pg_catalog.pg_class c "
                      "LEFT JOIN pg_catalog.pg_class t ON "
                      "  (c.reltoastrelid = t.oid) "
                      "WHERE c.oid = '%u'::pg_catalog.oid;",
                      pg_rel_oid);

    upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);

    pg_type_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "crel")));

    binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
                                             pg_type_oid);

    if (!PQgetisnull(upgrade_res, 0, PQfnumber(upgrade_res, "trel")))
    {
        /* Toast tables do not have pg_type array rows */
        Oid         pg_type_toast_oid = atooid(PQgetvalue(upgrade_res, 0,
                                            PQfnumber(upgrade_res, "trel")));

        appendPQExpBuffer(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type toast oid\n");
        appendPQExpBuffer(upgrade_buffer,
                          "SELECT binary_upgrade.set_next_toast_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                          pg_type_toast_oid);

        toast_set = true;
    }

    PQclear(upgrade_res);
    destroyPQExpBuffer(upgrade_query);

    return toast_set;
}

static void binary_upgrade_set_type_oids_by_type_oid ( Archive fout,
PQExpBuffer  upgrade_buffer,
Oid  pg_type_oid 
) [static]

Definition at line 2689 of file pg_dump.c.

References appendPQExpBuffer(), atooid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQueryForSingleRow(), OidIsValid, PQclear(), PQfnumber(), and PQgetvalue().

Referenced by binary_upgrade_set_type_oids_by_rel_oid(), dumpBaseType(), dumpCompositeType(), dumpDomain(), dumpEnumType(), dumpRangeType(), and dumpShellType().

{
    PQExpBuffer upgrade_query = createPQExpBuffer();
    PGresult   *upgrade_res;
    Oid         pg_type_array_oid;

    appendPQExpBuffer(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
    appendPQExpBuffer(upgrade_buffer,
     "SELECT binary_upgrade.set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                      pg_type_oid);

    /* we only support old >= 8.3 for binary upgrades */
    appendPQExpBuffer(upgrade_query,
                      "SELECT typarray "
                      "FROM pg_catalog.pg_type "
                      "WHERE pg_type.oid = '%u'::pg_catalog.oid;",
                      pg_type_oid);

    upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);

    pg_type_array_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "typarray")));

    if (OidIsValid(pg_type_array_oid))
    {
        appendPQExpBuffer(upgrade_buffer,
               "\n-- For binary upgrade, must preserve pg_type array oid\n");
        appendPQExpBuffer(upgrade_buffer,
                          "SELECT binary_upgrade.set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                          pg_type_array_oid);
    }

    PQclear(upgrade_res);
    destroyPQExpBuffer(upgrade_query);
}

static void BuildArchiveDependencies ( Archive fout  )  [static]

Definition at line 14946 of file pg_dump.c.

References _tocEntry::dependencies, _tocEntry::dumpId, findDumpableDependencies(), findObjectByDumpId(), free, _dumpableObject::nDeps, _tocEntry::nDeps, _tocEntry::next, NULL, pg_malloc(), pg_realloc(), _tocEntry::reqs, and _archiveHandle::toc.

Referenced by main().

{
    ArchiveHandle *AH = (ArchiveHandle *) fout;
    TocEntry   *te;

    /* Scan all TOC entries in the archive */
    for (te = AH->toc->next; te != AH->toc; te = te->next)
    {
        DumpableObject *dobj;
        DumpId     *dependencies;
        int         nDeps;
        int         allocDeps;

        /* No need to process entries that will not be dumped */
        if (te->reqs == 0)
            continue;
        /* Ignore entries that already have "special" dependencies */
        if (te->nDeps > 0)
            continue;
        /* Otherwise, look up the item's original DumpableObject, if any */
        dobj = findObjectByDumpId(te->dumpId);
        if (dobj == NULL)
            continue;
        /* No work if it has no dependencies */
        if (dobj->nDeps <= 0)
            continue;
        /* Set up work array */
        allocDeps = 64;
        dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
        nDeps = 0;
        /* Recursively find all dumpable dependencies */
        findDumpableDependencies(AH, dobj,
                                 &dependencies, &nDeps, &allocDeps);
        /* And save 'em ... */
        if (nDeps > 0)
        {
            dependencies = (DumpId *) pg_realloc(dependencies,
                                                 nDeps * sizeof(DumpId));
            te->dependencies = dependencies;
            te->nDeps = nDeps;
        }
        else
            free(dependencies);
    }
}

static void buildMatViewRefreshDependencies ( Archive fout  )  [static]

Definition at line 1875 of file pg_dump.c.

References addObjectDependency(), appendPQExpBuffer(), Assert, atooid, createPQExpBuffer(), PQExpBufferData::data, _tableInfo::dataObj, destroyPQExpBuffer(), DO_REFRESH_MATVIEW, DO_TABLE, _dumpableObject::dumpId, ExecuteSqlQuery(), findObjectByCatalogId(), i, _tableInfo::isscannable, NULL, _dumpableObject::objType, CatalogId::oid, PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), _tableInfo::relkind, RELKIND_MATVIEW, Archive::remoteVersion, selectSourceSchema(), and CatalogId::tableoid.

Referenced by main().

{
    PQExpBuffer query;
    PGresult   *res;
    int         ntups,
                i;
    int         i_classid,
                i_objid,
                i_refobjid;

    /* No Mat Views before 9.3. */
    if (fout->remoteVersion < 90300)
        return;

    /* Make sure we are in proper schema */
    selectSourceSchema(fout, "pg_catalog");

    query = createPQExpBuffer();

    appendPQExpBuffer(query, "with recursive w as "
                      "( "
                    "select d1.objid, d2.refobjid, c2.relkind as refrelkind "
                      "from pg_depend d1 "
                      "join pg_class c1 on c1.oid = d1.objid "
                      "and c1.relkind = 'm' "
                      "join pg_rewrite r1 on r1.ev_class = d1.objid "
                  "join pg_depend d2 on d2.classid = 'pg_rewrite'::regclass "
                      "and d2.objid = r1.oid "
                      "and d2.refobjid <> d1.objid "
                      "join pg_class c2 on c2.oid = d2.refobjid "
                      "and c2.relkind in ('m','v') "
                      "where d1.classid = 'pg_class'::regclass "
                      "union "
                      "select w.objid, d3.refobjid, c3.relkind "
                      "from w "
                      "join pg_rewrite r3 on r3.ev_class = w.refobjid "
                  "join pg_depend d3 on d3.classid = 'pg_rewrite'::regclass "
                      "and d3.objid = r3.oid "
                      "and d3.refobjid <> w.refobjid "
                      "join pg_class c3 on c3.oid = d3.refobjid "
                      "and c3.relkind in ('m','v') "
                      ") "
              "select 'pg_class'::regclass::oid as classid, objid, refobjid "
                      "from w "
                      "where refrelkind = 'm'");

    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    ntups = PQntuples(res);

    i_classid = PQfnumber(res, "classid");
    i_objid = PQfnumber(res, "objid");
    i_refobjid = PQfnumber(res, "refobjid");

    for (i = 0; i < ntups; i++)
    {
        CatalogId   objId;
        CatalogId   refobjId;
        DumpableObject *dobj;
        DumpableObject *refdobj;
        TableInfo  *tbinfo;
        TableInfo  *reftbinfo;

        objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
        objId.oid = atooid(PQgetvalue(res, i, i_objid));
        refobjId.tableoid = objId.tableoid;
        refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));

        dobj = findObjectByCatalogId(objId);
        if (dobj == NULL)
            continue;

        Assert(dobj->objType == DO_TABLE);
        tbinfo = (TableInfo *) dobj;
        Assert(tbinfo->relkind == RELKIND_MATVIEW);
        dobj = (DumpableObject *) tbinfo->dataObj;
        if (dobj == NULL)
            continue;
        Assert(dobj->objType == DO_REFRESH_MATVIEW);

        refdobj = findObjectByCatalogId(refobjId);
        if (refdobj == NULL)
            continue;

        Assert(refdobj->objType == DO_TABLE);
        reftbinfo = (TableInfo *) refdobj;
        Assert(reftbinfo->relkind == RELKIND_MATVIEW);
        refdobj = (DumpableObject *) reftbinfo->dataObj;
        if (refdobj == NULL)
            continue;
        Assert(refdobj->objType == DO_REFRESH_MATVIEW);

        addObjectDependency(dobj, refdobj->dumpId);

        if (!reftbinfo->isscannable)
            tbinfo->isscannable = false;
    }

    PQclear(res);

    destroyPQExpBuffer(query);
}

static int collectComments ( Archive fout,
CommentItem **  items 
) [static]

Definition at line 7567 of file pg_dump.c.

References appendPQExpBuffer(), atooid, CommentItem::classoid, createPQExpBuffer(), PQExpBufferData::data, CommentItem::descr, destroyPQExpBuffer(), ExecuteSqlQuery(), i, CommentItem::objoid, CommentItem::objsubid, pg_malloc(), PGRES_TUPLES_OK, PQfnumber(), PQgetvalue(), PQntuples(), and Archive::remoteVersion.

Referenced by findComments().

{
    PGresult   *res;
    PQExpBuffer query;
    int         i_description;
    int         i_classoid;
    int         i_objoid;
    int         i_objsubid;
    int         ntups;
    int         i;
    CommentItem *comments;

    /*
     * Note we do NOT change source schema here; preserve the caller's
     * setting, instead.
     */

    query = createPQExpBuffer();

    if (fout->remoteVersion >= 70300)
    {
        appendPQExpBuffer(query, "SELECT description, classoid, objoid, objsubid "
                          "FROM pg_catalog.pg_description "
                          "ORDER BY classoid, objoid, objsubid");
    }
    else if (fout->remoteVersion >= 70200)
    {
        appendPQExpBuffer(query, "SELECT description, classoid, objoid, objsubid "
                          "FROM pg_description "
                          "ORDER BY classoid, objoid, objsubid");
    }
    else
    {
        /* Note: this will fail to find attribute comments in pre-7.2... */
        appendPQExpBuffer(query, "SELECT description, 0 AS classoid, objoid, 0 AS objsubid "
                          "FROM pg_description "
                          "ORDER BY objoid");
    }

    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    /* Construct lookup table containing OIDs in numeric form */

    i_description = PQfnumber(res, "description");
    i_classoid = PQfnumber(res, "classoid");
    i_objoid = PQfnumber(res, "objoid");
    i_objsubid = PQfnumber(res, "objsubid");

    ntups = PQntuples(res);

    comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));

    for (i = 0; i < ntups; i++)
    {
        comments[i].descr = PQgetvalue(res, i, i_description);
        comments[i].classoid = atooid(PQgetvalue(res, i, i_classoid));
        comments[i].objoid = atooid(PQgetvalue(res, i, i_objoid));
        comments[i].objsubid = atoi(PQgetvalue(res, i, i_objsubid));
    }

    /* Do NOT free the PGresult since we are keeping pointers into it */
    destroyPQExpBuffer(query);

    *items = comments;
    return ntups;
}

static int collectSecLabels ( Archive fout,
SecLabelItem **  items 
) [static]

Definition at line 12610 of file pg_dump.c.

References appendPQExpBuffer(), atooid, SecLabelItem::classoid, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), ExecuteSqlQuery(), i, SecLabelItem::label, SecLabelItem::objoid, SecLabelItem::objsubid, pg_malloc(), PGRES_TUPLES_OK, PQfnumber(), PQgetvalue(), PQntuples(), and SecLabelItem::provider.

Referenced by findSecLabels().

{
    PGresult   *res;
    PQExpBuffer query;
    int         i_label;
    int         i_provider;
    int         i_classoid;
    int         i_objoid;
    int         i_objsubid;
    int         ntups;
    int         i;
    SecLabelItem *labels;

    query = createPQExpBuffer();

    appendPQExpBuffer(query,
                      "SELECT label, provider, classoid, objoid, objsubid "
                      "FROM pg_catalog.pg_seclabel "
                      "ORDER BY classoid, objoid, objsubid");

    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    /* Construct lookup table containing OIDs in numeric form */
    i_label = PQfnumber(res, "label");
    i_provider = PQfnumber(res, "provider");
    i_classoid = PQfnumber(res, "classoid");
    i_objoid = PQfnumber(res, "objoid");
    i_objsubid = PQfnumber(res, "objsubid");

    ntups = PQntuples(res);

    labels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));

    for (i = 0; i < ntups; i++)
    {
        labels[i].label = PQgetvalue(res, i, i_label);
        labels[i].provider = PQgetvalue(res, i, i_provider);
        labels[i].classoid = atooid(PQgetvalue(res, i, i_classoid));
        labels[i].objoid = atooid(PQgetvalue(res, i, i_objoid));
        labels[i].objsubid = atoi(PQgetvalue(res, i, i_objsubid));
    }

    /* Do NOT free the PGresult since we are keeping pointers into it */
    destroyPQExpBuffer(query);

    *items = labels;
    return ntups;
}

static const char * convertOperatorReference ( Archive fout,
const char *  opr 
) [static]

Definition at line 10392 of file pg_dump.c.

References atooid, _oprInfo::dobj, findOprByOid(), free, _dumpableObject::name, name, NULL, pg_malloc(), pg_strdup(), Archive::remoteVersion, and write_msg().

Referenced by dumpAgg(), and dumpOpr().

{
    OprInfo    *oprInfo;

    /* In all cases "0" means a null reference */
    if (strcmp(opr, "0") == 0)
        return NULL;

    if (fout->remoteVersion >= 70300)
    {
        char       *name;
        char       *oname;
        char       *ptr;
        bool        inquote;
        bool        sawdot;

        name = pg_strdup(opr);
        /* find non-double-quoted left paren, and check for non-quoted dot */
        inquote = false;
        sawdot = false;
        for (ptr = name; *ptr; ptr++)
        {
            if (*ptr == '"')
                inquote = !inquote;
            else if (*ptr == '.' && !inquote)
                sawdot = true;
            else if (*ptr == '(' && !inquote)
            {
                *ptr = '\0';
                break;
            }
        }
        /* If not schema-qualified, don't need to add OPERATOR() */
        if (!sawdot)
            return name;
        oname = pg_malloc(strlen(name) + 11);
        sprintf(oname, "OPERATOR(%s)", name);
        free(name);
        return oname;
    }

    oprInfo = findOprByOid(atooid(opr));
    if (oprInfo == NULL)
    {
        write_msg(NULL, "WARNING: could not find operator with OID %s\n",
                  opr);
        return NULL;
    }
    return oprInfo->dobj.name;
}

static const char * convertRegProcReference ( Archive fout,
const char *  proc 
) [static]

Definition at line 10349 of file pg_dump.c.

References fmtId(), name, pg_strdup(), and Archive::remoteVersion.

Referenced by dumpOpr().

{
    /* In all cases "-" means a null reference */
    if (strcmp(proc, "-") == 0)
        return NULL;

    if (fout->remoteVersion >= 70300)
    {
        char       *name;
        char       *paren;
        bool        inquote;

        name = pg_strdup(proc);
        /* find non-double-quoted left paren */
        inquote = false;
        for (paren = name; *paren; paren++)
        {
            if (*paren == '(' && !inquote)
            {
                *paren = '\0';
                break;
            }
            if (*paren == '"')
                inquote = !inquote;
        }
        return name;
    }

    /* REGPROC before 7.3 does not quote its result */
    return fmtId(proc);
}

static const char * convertTSFunction ( Archive fout,
Oid  funcOid 
) [static]

Definition at line 10452 of file pg_dump.c.

References ExecuteSqlQueryForSingleRow(), pg_strdup(), PQclear(), PQgetvalue(), and snprintf().

Referenced by dumpTSParser(), and dumpTSTemplate().

{
    char       *result;
    char        query[128];
    PGresult   *res;

    snprintf(query, sizeof(query),
             "SELECT '%u'::pg_catalog.regproc", funcOid);
    res = ExecuteSqlQueryForSingleRow(fout, query);

    result = pg_strdup(PQgetvalue(res, 0, 0));

    PQclear(res);

    return result;
}

static DumpableObject * createBoundaryObjects ( void   )  [static]

Definition at line 14818 of file pg_dump.c.

References AssignDumpId(), _dumpableObject::catId, _dumpableObject::name, _dumpableObject::objType, pg_malloc(), and pg_strdup().

Referenced by main().

{
    DumpableObject *dobjs;

    dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));

    dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
    dobjs[0].catId = nilCatalogId;
    AssignDumpId(dobjs + 0);
    dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");

    dobjs[1].objType = DO_POST_DATA_BOUNDARY;
    dobjs[1].catId = nilCatalogId;
    AssignDumpId(dobjs + 1);
    dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");

    return dobjs;
}

static PQExpBuffer createViewAsClause ( Archive fout,
TableInfo tbinfo 
) [static]

Definition at line 12735 of file pg_dump.c.

References appendBinaryPQExpBuffer(), appendPQExpBuffer(), appendStringLiteralAH, Assert, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, ExecuteSqlQuery(), exit_horribly(), _dumpableObject::name, NULL, CatalogId::oid, PGRES_TUPLES_OK, PQclear(), PQgetlength(), PQgetvalue(), PQntuples(), and Archive::remoteVersion.

Referenced by dumpTableSchema().

{
    PQExpBuffer query = createPQExpBuffer();
    PQExpBuffer result = createPQExpBuffer();
    PGresult   *res;
    int         len;

    /* Fetch the view definition */
    if (fout->remoteVersion >= 70300)
    {
        /* Beginning in 7.3, viewname is not unique; rely on OID */
        appendPQExpBuffer(query,
         "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
                          tbinfo->dobj.catId.oid);
    }
    else
    {
        appendPQExpBuffer(query, "SELECT definition AS viewdef "
                          "FROM pg_views WHERE viewname = ");
        appendStringLiteralAH(query, tbinfo->dobj.name, fout);
        appendPQExpBuffer(query, ";");
    }

    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    if (PQntuples(res) != 1)
    {
        if (PQntuples(res) < 1)
            exit_horribly(NULL, "query to obtain definition of view \"%s\" returned no data\n",
                          tbinfo->dobj.name);
        else
            exit_horribly(NULL, "query to obtain definition of view \"%s\" returned more than one definition\n",
                          tbinfo->dobj.name);
    }

    len = PQgetlength(res, 0, 0);

    if (len == 0)
        exit_horribly(NULL, "definition of view \"%s\" appears to be empty (length zero)\n",
                      tbinfo->dobj.name);

    /* Strip off the trailing semicolon so that other things may follow. */
    Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
    appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);

    PQclear(res);
    destroyPQExpBuffer(query);

    return result;
}

static void dumpACL ( Archive fout,
CatalogId  objCatId,
DumpId  objDumpId,
const char *  type,
const char *  name,
const char *  subname,
const char *  tag,
const char *  nspname,
const char *  owner,
const char *  acls 
) [static]

Definition at line 12324 of file pg_dump.c.

References aclsSkip, ArchiveEntry(), buildACLCommands(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), exit_horribly(), PQExpBufferData::len, NULL, Archive::remoteVersion, and SECTION_NONE.

Referenced by dumpAgg(), dumpBaseType(), dumpBlob(), dumpCompositeType(), dumpDomain(), dumpEnumType(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpNamespace(), dumpProcLang(), dumpRangeType(), and dumpTable().

{
    PQExpBuffer sql;

    /* Do nothing if ACL dump is not enabled */
    if (aclsSkip)
        return;

    /* --data-only skips ACLs *except* BLOB ACLs */
    if (dataOnly && strcmp(type, "LARGE OBJECT") != 0)
        return;

    sql = createPQExpBuffer();

    if (!buildACLCommands(name, subname, type, acls, owner,
                          "", fout->remoteVersion, sql))
        exit_horribly(NULL,
                    "could not parse ACL list (%s) for object \"%s\" (%s)\n",
                      acls, name, type);

    if (sql->len > 0)
        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                     tag, nspname,
                     NULL,
                     owner ? owner : "",
                     false, "ACL", SECTION_NONE,
                     sql->data, "", NULL,
                     &(objDumpId), 1,
                     NULL, NULL);

    destroyPQExpBuffer(sql);
}

static void dumpAgg ( Archive fout,
AggInfo agginfo 
) [static]

Definition at line 11392 of file pg_dump.c.

References _aggInfo::aggfn, appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, convertOperatorReference(), createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _funcInfo::dobj, _dumpableObject::dump, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), ExecuteSqlQueryForSingleRow(), fmtId(), format_aggregate_signature(), format_function_signature(), free, _dumpableObject::name, NULL, CatalogId::oid, PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), _funcInfo::proacl, Archive::remoteVersion, _funcInfo::rolname, SECTION_PRE_DATA, selectSourceSchema(), and write_msg().

Referenced by dumpDumpableObject().

{
    PQExpBuffer query;
    PQExpBuffer q;
    PQExpBuffer delq;
    PQExpBuffer labelq;
    PQExpBuffer details;
    char       *aggsig;
    char       *aggsig_tag;
    PGresult   *res;
    int         i_aggtransfn;
    int         i_aggfinalfn;
    int         i_aggsortop;
    int         i_aggtranstype;
    int         i_agginitval;
    int         i_convertok;
    const char *aggtransfn;
    const char *aggfinalfn;
    const char *aggsortop;
    const char *aggtranstype;
    const char *agginitval;
    bool        convertok;

    /* Skip if not to be dumped */
    if (!agginfo->aggfn.dobj.dump || dataOnly)
        return;

    query = createPQExpBuffer();
    q = createPQExpBuffer();
    delq = createPQExpBuffer();
    labelq = createPQExpBuffer();
    details = createPQExpBuffer();

    /* Make sure we are in proper schema */
    selectSourceSchema(fout, agginfo->aggfn.dobj.namespace->dobj.name);

    /* Get aggregate-specific details */
    if (fout->remoteVersion >= 80100)
    {
        appendPQExpBuffer(query, "SELECT aggtransfn, "
                          "aggfinalfn, aggtranstype::pg_catalog.regtype, "
                          "aggsortop::pg_catalog.regoperator, "
                          "agginitval, "
                          "'t'::boolean AS convertok "
                      "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
                          "WHERE a.aggfnoid = p.oid "
                          "AND p.oid = '%u'::pg_catalog.oid",
                          agginfo->aggfn.dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 70300)
    {
        appendPQExpBuffer(query, "SELECT aggtransfn, "
                          "aggfinalfn, aggtranstype::pg_catalog.regtype, "
                          "0 AS aggsortop, "
                          "agginitval, "
                          "'t'::boolean AS convertok "
                      "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
                          "WHERE a.aggfnoid = p.oid "
                          "AND p.oid = '%u'::pg_catalog.oid",
                          agginfo->aggfn.dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 70100)
    {
        appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, "
                          "format_type(aggtranstype, NULL) AS aggtranstype, "
                          "0 AS aggsortop, "
                          "agginitval, "
                          "'t'::boolean AS convertok "
                          "FROM pg_aggregate "
                          "WHERE oid = '%u'::oid",
                          agginfo->aggfn.dobj.catId.oid);
    }
    else
    {
        appendPQExpBuffer(query, "SELECT aggtransfn1 AS aggtransfn, "
                          "aggfinalfn, "
                          "(SELECT typname FROM pg_type WHERE oid = aggtranstype1) AS aggtranstype, "
                          "0 AS aggsortop, "
                          "agginitval1 AS agginitval, "
                          "(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) AS convertok "
                          "FROM pg_aggregate "
                          "WHERE oid = '%u'::oid",
                          agginfo->aggfn.dobj.catId.oid);
    }

    res = ExecuteSqlQueryForSingleRow(fout, query->data);

    i_aggtransfn = PQfnumber(res, "aggtransfn");
    i_aggfinalfn = PQfnumber(res, "aggfinalfn");
    i_aggsortop = PQfnumber(res, "aggsortop");
    i_aggtranstype = PQfnumber(res, "aggtranstype");
    i_agginitval = PQfnumber(res, "agginitval");
    i_convertok = PQfnumber(res, "convertok");

    aggtransfn = PQgetvalue(res, 0, i_aggtransfn);
    aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn);
    aggsortop = PQgetvalue(res, 0, i_aggsortop);
    aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
    agginitval = PQgetvalue(res, 0, i_agginitval);
    convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't');

    aggsig = format_aggregate_signature(agginfo, fout, true);
    aggsig_tag = format_aggregate_signature(agginfo, fout, false);

    if (!convertok)
    {
        write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
                  aggsig);
        return;
    }

    if (fout->remoteVersion >= 70300)
    {
        /* If using 7.3's regproc or regtype, data is already quoted */
        appendPQExpBuffer(details, "    SFUNC = %s,\n    STYPE = %s",
                          aggtransfn,
                          aggtranstype);
    }
    else if (fout->remoteVersion >= 70100)
    {
        /* format_type quotes, regproc does not */
        appendPQExpBuffer(details, "    SFUNC = %s,\n    STYPE = %s",
                          fmtId(aggtransfn),
                          aggtranstype);
    }
    else
    {
        /* need quotes all around */
        appendPQExpBuffer(details, "    SFUNC = %s,\n",
                          fmtId(aggtransfn));
        appendPQExpBuffer(details, "    STYPE = %s",
                          fmtId(aggtranstype));
    }

    if (!PQgetisnull(res, 0, i_agginitval))
    {
        appendPQExpBuffer(details, ",\n    INITCOND = ");
        appendStringLiteralAH(details, agginitval, fout);
    }

    if (strcmp(aggfinalfn, "-") != 0)
    {
        appendPQExpBuffer(details, ",\n    FINALFUNC = %s",
                          aggfinalfn);
    }

    aggsortop = convertOperatorReference(fout, aggsortop);
    if (aggsortop)
    {
        appendPQExpBuffer(details, ",\n    SORTOP = %s",
                          aggsortop);
    }

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
                      fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
                      aggsig);

    appendPQExpBuffer(q, "CREATE AGGREGATE %s (\n%s\n);\n",
                      aggsig, details->data);

    appendPQExpBuffer(labelq, "AGGREGATE %s", aggsig);

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &agginfo->aggfn.dobj, labelq->data);

    ArchiveEntry(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId,
                 aggsig_tag,
                 agginfo->aggfn.dobj.namespace->dobj.name,
                 NULL,
                 agginfo->aggfn.rolname,
                 false, "AGGREGATE", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Aggregate Comments */
    dumpComment(fout, labelq->data,
            agginfo->aggfn.dobj.namespace->dobj.name, agginfo->aggfn.rolname,
                agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
    dumpSecLabel(fout, labelq->data,
            agginfo->aggfn.dobj.namespace->dobj.name, agginfo->aggfn.rolname,
                 agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);

    /*
     * Since there is no GRANT ON AGGREGATE syntax, we have to make the ACL
     * command look like a function's GRANT; in particular this affects the
     * syntax for zero-argument aggregates.
     */
    free(aggsig);
    free(aggsig_tag);

    aggsig = format_function_signature(fout, &agginfo->aggfn, true);
    aggsig_tag = format_function_signature(fout, &agginfo->aggfn, false);

    dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId,
            "FUNCTION",
            aggsig, NULL, aggsig_tag,
            agginfo->aggfn.dobj.namespace->dobj.name,
            agginfo->aggfn.rolname, agginfo->aggfn.proacl);

    free(aggsig);
    free(aggsig_tag);

    PQclear(res);

    destroyPQExpBuffer(query);
    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
    destroyPQExpBuffer(details);
}

static void dumpAttrDef ( Archive fout,
AttrDefInfo adinfo 
) [static]

Definition at line 13379 of file pg_dump.c.

References _attrDefInfo::adef_expr, _attrDefInfo::adnum, _attrDefInfo::adtable, appendPQExpBuffer(), ArchiveEntry(), _tableInfo::attnames, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _attrDefInfo::dobj, _tableInfo::dobj, _dumpableObject::dump, _dumpableObject::dumpId, fmtId(), _dumpableObject::name, NULL, _tableInfo::rolname, SECTION_PRE_DATA, and _attrDefInfo::separate.

Referenced by dumpDumpableObject().

{
    TableInfo  *tbinfo = adinfo->adtable;
    int         adnum = adinfo->adnum;
    PQExpBuffer q;
    PQExpBuffer delq;

    /* Skip if table definition not to be dumped */
    if (!tbinfo->dobj.dump || dataOnly)
        return;

    /* Skip if not "separate"; it was dumped in the table's definition */
    if (!adinfo->separate)
        return;

    q = createPQExpBuffer();
    delq = createPQExpBuffer();

    appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
                      fmtId(tbinfo->dobj.name));
    appendPQExpBuffer(q, "ALTER COLUMN %s SET DEFAULT %s;\n",
                      fmtId(tbinfo->attnames[adnum - 1]),
                      adinfo->adef_expr);

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delq, "ALTER TABLE %s.",
                      fmtId(tbinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delq, "%s ",
                      fmtId(tbinfo->dobj.name));
    appendPQExpBuffer(delq, "ALTER COLUMN %s DROP DEFAULT;\n",
                      fmtId(tbinfo->attnames[adnum - 1]));

    ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
                 tbinfo->attnames[adnum - 1],
                 tbinfo->dobj.namespace->dobj.name,
                 NULL,
                 tbinfo->rolname,
                 false, "DEFAULT", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
}

static void dumpBaseType ( Archive fout,
TypeInfo tyinfo 
) [static]

Definition at line 8240 of file pg_dump.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ArchiveEntry(), atooid, binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_type_oids_by_type_oid(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), dumpACL(), dumpComment(), dumpSecLabel(), ExecuteSqlQueryForSingleRow(), fmtId(), free, getFormattedTypeName(), NULL, OidIsValid, pg_strdup(), PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), Archive::remoteVersion, SECTION_PRE_DATA, selectSourceSchema(), and zeroAsOpaque.

Referenced by dumpType().

{
    PQExpBuffer q = createPQExpBuffer();
    PQExpBuffer delq = createPQExpBuffer();
    PQExpBuffer labelq = createPQExpBuffer();
    PQExpBuffer query = createPQExpBuffer();
    PGresult   *res;
    char       *qtypname;
    char       *typlen;
    char       *typinput;
    char       *typoutput;
    char       *typreceive;
    char       *typsend;
    char       *typmodin;
    char       *typmodout;
    char       *typanalyze;
    Oid         typreceiveoid;
    Oid         typsendoid;
    Oid         typmodinoid;
    Oid         typmodoutoid;
    Oid         typanalyzeoid;
    char       *typcategory;
    char       *typispreferred;
    char       *typdelim;
    char       *typbyval;
    char       *typalign;
    char       *typstorage;
    char       *typcollatable;
    char       *typdefault;
    bool        typdefault_is_literal = false;

    /* Set proper schema search path so regproc references list correctly */
    selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);

    /* Fetch type-specific details */
    if (fout->remoteVersion >= 90100)
    {
        appendPQExpBuffer(query, "SELECT typlen, "
                          "typinput, typoutput, typreceive, typsend, "
                          "typmodin, typmodout, typanalyze, "
                          "typreceive::pg_catalog.oid AS typreceiveoid, "
                          "typsend::pg_catalog.oid AS typsendoid, "
                          "typmodin::pg_catalog.oid AS typmodinoid, "
                          "typmodout::pg_catalog.oid AS typmodoutoid, "
                          "typanalyze::pg_catalog.oid AS typanalyzeoid, "
                          "typcategory, typispreferred, "
                          "typdelim, typbyval, typalign, typstorage, "
                          "(typcollation <> 0) AS typcollatable, "
                          "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault "
                          "FROM pg_catalog.pg_type "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          tyinfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 80400)
    {
        appendPQExpBuffer(query, "SELECT typlen, "
                          "typinput, typoutput, typreceive, typsend, "
                          "typmodin, typmodout, typanalyze, "
                          "typreceive::pg_catalog.oid AS typreceiveoid, "
                          "typsend::pg_catalog.oid AS typsendoid, "
                          "typmodin::pg_catalog.oid AS typmodinoid, "
                          "typmodout::pg_catalog.oid AS typmodoutoid, "
                          "typanalyze::pg_catalog.oid AS typanalyzeoid, "
                          "typcategory, typispreferred, "
                          "typdelim, typbyval, typalign, typstorage, "
                          "false AS typcollatable, "
                          "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault "
                          "FROM pg_catalog.pg_type "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          tyinfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 80300)
    {
        /* Before 8.4, pg_get_expr does not allow 0 for its second arg */
        appendPQExpBuffer(query, "SELECT typlen, "
                          "typinput, typoutput, typreceive, typsend, "
                          "typmodin, typmodout, typanalyze, "
                          "typreceive::pg_catalog.oid AS typreceiveoid, "
                          "typsend::pg_catalog.oid AS typsendoid, "
                          "typmodin::pg_catalog.oid AS typmodinoid, "
                          "typmodout::pg_catalog.oid AS typmodoutoid, "
                          "typanalyze::pg_catalog.oid AS typanalyzeoid, "
                          "'U' AS typcategory, false AS typispreferred, "
                          "typdelim, typbyval, typalign, typstorage, "
                          "false AS typcollatable, "
                          "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, typdefault "
                          "FROM pg_catalog.pg_type "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          tyinfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 80000)
    {
        appendPQExpBuffer(query, "SELECT typlen, "
                          "typinput, typoutput, typreceive, typsend, "
                          "'-' AS typmodin, '-' AS typmodout, "
                          "typanalyze, "
                          "typreceive::pg_catalog.oid AS typreceiveoid, "
                          "typsend::pg_catalog.oid AS typsendoid, "
                          "0 AS typmodinoid, 0 AS typmodoutoid, "
                          "typanalyze::pg_catalog.oid AS typanalyzeoid, "
                          "'U' AS typcategory, false AS typispreferred, "
                          "typdelim, typbyval, typalign, typstorage, "
                          "false AS typcollatable, "
                          "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, typdefault "
                          "FROM pg_catalog.pg_type "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          tyinfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 70400)
    {
        appendPQExpBuffer(query, "SELECT typlen, "
                          "typinput, typoutput, typreceive, typsend, "
                          "'-' AS typmodin, '-' AS typmodout, "
                          "'-' AS typanalyze, "
                          "typreceive::pg_catalog.oid AS typreceiveoid, "
                          "typsend::pg_catalog.oid AS typsendoid, "
                          "0 AS typmodinoid, 0 AS typmodoutoid, "
                          "0 AS typanalyzeoid, "
                          "'U' AS typcategory, false AS typispreferred, "
                          "typdelim, typbyval, typalign, typstorage, "
                          "false AS typcollatable, "
                          "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, typdefault "
                          "FROM pg_catalog.pg_type "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          tyinfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 70300)
    {
        appendPQExpBuffer(query, "SELECT typlen, "
                          "typinput, typoutput, "
                          "'-' AS typreceive, '-' AS typsend, "
                          "'-' AS typmodin, '-' AS typmodout, "
                          "'-' AS typanalyze, "
                          "0 AS typreceiveoid, 0 AS typsendoid, "
                          "0 AS typmodinoid, 0 AS typmodoutoid, "
                          "0 AS typanalyzeoid, "
                          "'U' AS typcategory, false AS typispreferred, "
                          "typdelim, typbyval, typalign, typstorage, "
                          "false AS typcollatable, "
                          "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, typdefault "
                          "FROM pg_catalog.pg_type "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          tyinfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 70200)
    {
        /*
         * Note: although pre-7.3 catalogs contain typreceive and typsend,
         * ignore them because they are not right.
         */
        appendPQExpBuffer(query, "SELECT typlen, "
                          "typinput, typoutput, "
                          "'-' AS typreceive, '-' AS typsend, "
                          "'-' AS typmodin, '-' AS typmodout, "
                          "'-' AS typanalyze, "
                          "0 AS typreceiveoid, 0 AS typsendoid, "
                          "0 AS typmodinoid, 0 AS typmodoutoid, "
                          "0 AS typanalyzeoid, "
                          "'U' AS typcategory, false AS typispreferred, "
                          "typdelim, typbyval, typalign, typstorage, "
                          "false AS typcollatable, "
                          "NULL AS typdefaultbin, typdefault "
                          "FROM pg_type "
                          "WHERE oid = '%u'::oid",
                          tyinfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 70100)
    {
        /*
         * Ignore pre-7.2 typdefault; the field exists but has an unusable
         * representation.
         */
        appendPQExpBuffer(query, "SELECT typlen, "
                          "typinput, typoutput, "
                          "'-' AS typreceive, '-' AS typsend, "
                          "'-' AS typmodin, '-' AS typmodout, "
                          "'-' AS typanalyze, "
                          "0 AS typreceiveoid, 0 AS typsendoid, "
                          "0 AS typmodinoid, 0 AS typmodoutoid, "
                          "0 AS typanalyzeoid, "
                          "'U' AS typcategory, false AS typispreferred, "
                          "typdelim, typbyval, typalign, typstorage, "
                          "false AS typcollatable, "
                          "NULL AS typdefaultbin, NULL AS typdefault "
                          "FROM pg_type "
                          "WHERE oid = '%u'::oid",
                          tyinfo->dobj.catId.oid);
    }
    else
    {
        appendPQExpBuffer(query, "SELECT typlen, "
                          "typinput, typoutput, "
                          "'-' AS typreceive, '-' AS typsend, "
                          "'-' AS typmodin, '-' AS typmodout, "
                          "'-' AS typanalyze, "
                          "0 AS typreceiveoid, 0 AS typsendoid, "
                          "0 AS typmodinoid, 0 AS typmodoutoid, "
                          "0 AS typanalyzeoid, "
                          "'U' AS typcategory, false AS typispreferred, "
                          "typdelim, typbyval, typalign, "
                          "'p'::char AS typstorage, "
                          "false AS typcollatable, "
                          "NULL AS typdefaultbin, NULL AS typdefault "
                          "FROM pg_type "
                          "WHERE oid = '%u'::oid",
                          tyinfo->dobj.catId.oid);
    }

    res = ExecuteSqlQueryForSingleRow(fout, query->data);

    typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen"));
    typinput = PQgetvalue(res, 0, PQfnumber(res, "typinput"));
    typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
    typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
    typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
    typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin"));
    typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout"));
    typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
    typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
    typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
    typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
    typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
    typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
    typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory"));
    typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred"));
    typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
    typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
    typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
    typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
    typcollatable = PQgetvalue(res, 0, PQfnumber(res, "typcollatable"));
    if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
        typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
    else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
    {
        typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
        typdefault_is_literal = true;   /* it needs quotes */
    }
    else
        typdefault = NULL;

    qtypname = pg_strdup(fmtId(tyinfo->dobj.name));

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog.
     * The reason we include CASCADE is that the circular dependency between
     * the type and its I/O functions makes it impossible to drop the type any
     * other way.
     */
    appendPQExpBuffer(delq, "DROP TYPE %s.",
                      fmtId(tyinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delq, "%s CASCADE;\n",
                      qtypname);

    /* We might already have a shell type, but setting pg_type_oid is harmless */
    if (binary_upgrade)
        binary_upgrade_set_type_oids_by_type_oid(fout, q,
                                                 tyinfo->dobj.catId.oid);

    appendPQExpBuffer(q,
                      "CREATE TYPE %s (\n"
                      "    INTERNALLENGTH = %s",
                      qtypname,
                      (strcmp(typlen, "-1") == 0) ? "variable" : typlen);

    if (fout->remoteVersion >= 70300)
    {
        /* regproc result is correctly quoted as of 7.3 */
        appendPQExpBuffer(q, ",\n    INPUT = %s", typinput);
        appendPQExpBuffer(q, ",\n    OUTPUT = %s", typoutput);
        if (OidIsValid(typreceiveoid))
            appendPQExpBuffer(q, ",\n    RECEIVE = %s", typreceive);
        if (OidIsValid(typsendoid))
            appendPQExpBuffer(q, ",\n    SEND = %s", typsend);
        if (OidIsValid(typmodinoid))
            appendPQExpBuffer(q, ",\n    TYPMOD_IN = %s", typmodin);
        if (OidIsValid(typmodoutoid))
            appendPQExpBuffer(q, ",\n    TYPMOD_OUT = %s", typmodout);
        if (OidIsValid(typanalyzeoid))
            appendPQExpBuffer(q, ",\n    ANALYZE = %s", typanalyze);
    }
    else
    {
        /* regproc delivers an unquoted name before 7.3 */
        /* cannot combine these because fmtId uses static result area */
        appendPQExpBuffer(q, ",\n    INPUT = %s", fmtId(typinput));
        appendPQExpBuffer(q, ",\n    OUTPUT = %s", fmtId(typoutput));
        /* receive/send/typmodin/typmodout/analyze need not be printed */
    }

    if (strcmp(typcollatable, "t") == 0)
        appendPQExpBuffer(q, ",\n    COLLATABLE = true");

    if (typdefault != NULL)
    {
        appendPQExpBuffer(q, ",\n    DEFAULT = ");
        if (typdefault_is_literal)
            appendStringLiteralAH(q, typdefault, fout);
        else
            appendPQExpBufferStr(q, typdefault);
    }

    if (OidIsValid(tyinfo->typelem))
    {
        char       *elemType;

        /* reselect schema in case changed by function dump */
        selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
        elemType = getFormattedTypeName(fout, tyinfo->typelem, zeroAsOpaque);
        appendPQExpBuffer(q, ",\n    ELEMENT = %s", elemType);
        free(elemType);
    }

    if (strcmp(typcategory, "U") != 0)
    {
        appendPQExpBuffer(q, ",\n    CATEGORY = ");
        appendStringLiteralAH(q, typcategory, fout);
    }

    if (strcmp(typispreferred, "t") == 0)
        appendPQExpBuffer(q, ",\n    PREFERRED = true");

    if (typdelim && strcmp(typdelim, ",") != 0)
    {
        appendPQExpBuffer(q, ",\n    DELIMITER = ");
        appendStringLiteralAH(q, typdelim, fout);
    }

    if (strcmp(typalign, "c") == 0)
        appendPQExpBuffer(q, ",\n    ALIGNMENT = char");
    else if (strcmp(typalign, "s") == 0)
        appendPQExpBuffer(q, ",\n    ALIGNMENT = int2");
    else if (strcmp(typalign, "i") == 0)
        appendPQExpBuffer(q, ",\n    ALIGNMENT = int4");
    else if (strcmp(typalign, "d") == 0)
        appendPQExpBuffer(q, ",\n    ALIGNMENT = double");

    if (strcmp(typstorage, "p") == 0)
        appendPQExpBuffer(q, ",\n    STORAGE = plain");
    else if (strcmp(typstorage, "e") == 0)
        appendPQExpBuffer(q, ",\n    STORAGE = external");
    else if (strcmp(typstorage, "x") == 0)
        appendPQExpBuffer(q, ",\n    STORAGE = extended");
    else if (strcmp(typstorage, "m") == 0)
        appendPQExpBuffer(q, ",\n    STORAGE = main");

    if (strcmp(typbyval, "t") == 0)
        appendPQExpBuffer(q, ",\n    PASSEDBYVALUE");

    appendPQExpBuffer(q, "\n);\n");

    appendPQExpBuffer(labelq, "TYPE %s", qtypname);

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);

    ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
                 tyinfo->dobj.name,
                 tyinfo->dobj.namespace->dobj.name,
                 NULL,
                 tyinfo->rolname, false,
                 "TYPE", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Type Comments and Security Labels */
    dumpComment(fout, labelq->data,
                tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
    dumpSecLabel(fout, labelq->data,
                 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);

    dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
            qtypname, NULL, tyinfo->dobj.name,
            tyinfo->dobj.namespace->dobj.name,
            tyinfo->rolname, tyinfo->typacl);

    PQclear(res);
    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
    destroyPQExpBuffer(query);
}

static void dumpBlob ( Archive fout,
BlobInfo binfo 
) [static]

Definition at line 2561 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), _blobInfo::blobacl, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _blobInfo::dobj, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), _dumpableObject::name, NULL, resetPQExpBuffer(), _blobInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

{
    PQExpBuffer cquery = createPQExpBuffer();
    PQExpBuffer dquery = createPQExpBuffer();

    appendPQExpBuffer(cquery,
                      "SELECT pg_catalog.lo_create('%s');\n",
                      binfo->dobj.name);

    appendPQExpBuffer(dquery,
                      "SELECT pg_catalog.lo_unlink('%s');\n",
                      binfo->dobj.name);

    ArchiveEntry(fout, binfo->dobj.catId, binfo->dobj.dumpId,
                 binfo->dobj.name,
                 NULL, NULL,
                 binfo->rolname, false,
                 "BLOB", SECTION_PRE_DATA,
                 cquery->data, dquery->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* set up tag for comment and/or ACL */
    resetPQExpBuffer(cquery);
    appendPQExpBuffer(cquery, "LARGE OBJECT %s", binfo->dobj.name);

    /* Dump comment if any */
    dumpComment(fout, cquery->data,
                NULL, binfo->rolname,
                binfo->dobj.catId, 0, binfo->dobj.dumpId);

    /* Dump security label if any */
    dumpSecLabel(fout, cquery->data,
                 NULL, binfo->rolname,
                 binfo->dobj.catId, 0, binfo->dobj.dumpId);

    /* Dump ACL if any */
    if (binfo->blobacl)
        dumpACL(fout, binfo->dobj.catId, binfo->dobj.dumpId, "LARGE OBJECT",
                binfo->dobj.name, NULL, cquery->data,
                NULL, binfo->rolname, binfo->blobacl);

    destroyPQExpBuffer(cquery);
    destroyPQExpBuffer(dquery);
}

static int dumpBlobs ( Archive fout,
void *  arg 
) [static]

Definition at line 2612 of file pg_dump.c.

References atooid, buf, conn, EndBlob(), ExecuteSqlQuery(), ExecuteSqlStatement(), exit_horribly(), g_verbose, GetConnection(), i, INV_READ, lo_close(), lo_open(), lo_read(), LOBBUFSIZE, NULL, PGRES_TUPLES_OK, PQclear(), PQerrorMessage(), PQgetvalue(), PQntuples(), Archive::remoteVersion, selectSourceSchema(), StartBlob(), write_msg(), and WriteData().

Referenced by dumpDumpableObject().

{
    const char *blobQry;
    const char *blobFetchQry;
    PGconn     *conn = GetConnection(fout);
    PGresult   *res;
    char        buf[LOBBUFSIZE];
    int         ntups;
    int         i;
    int         cnt;

    if (g_verbose)
        write_msg(NULL, "saving large objects\n");

    /* Make sure we are in proper schema */
    selectSourceSchema(fout, "pg_catalog");

    /*
     * Currently, we re-fetch all BLOB OIDs using a cursor.  Consider scanning
     * the already-in-memory dumpable objects instead...
     */
    if (fout->remoteVersion >= 90000)
        blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_largeobject_metadata";
    else if (fout->remoteVersion >= 70100)
        blobQry = "DECLARE bloboid CURSOR FOR SELECT DISTINCT loid FROM pg_largeobject";
    else
        blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_class WHERE relkind = 'l'";

    ExecuteSqlStatement(fout, blobQry);

    /* Command to fetch from cursor */
    blobFetchQry = "FETCH 1000 IN bloboid";

    do
    {
        /* Do a fetch */
        res = ExecuteSqlQuery(fout, blobFetchQry, PGRES_TUPLES_OK);

        /* Process the tuples, if any */
        ntups = PQntuples(res);
        for (i = 0; i < ntups; i++)
        {
            Oid         blobOid;
            int         loFd;

            blobOid = atooid(PQgetvalue(res, i, 0));
            /* Open the BLOB */
            loFd = lo_open(conn, blobOid, INV_READ);
            if (loFd == -1)
                exit_horribly(NULL, "could not open large object %u: %s",
                              blobOid, PQerrorMessage(conn));

            StartBlob(fout, blobOid);

            /* Now read it in chunks, sending data to archive */
            do
            {
                cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
                if (cnt < 0)
                    exit_horribly(NULL, "error reading large object %u: %s",
                                  blobOid, PQerrorMessage(conn));

                WriteData(fout, buf, cnt);
            } while (cnt > 0);

            lo_close(conn, loFd);

            EndBlob(fout, blobOid);
        }

        PQclear(res);
    } while (ntups > 0);

    return 1;
}

static void dumpCast ( Archive fout,
CastInfo cast 
) [static]

Definition at line 9958 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _castInfo::castcontext, _castInfo::castfunc, _castInfo::castmethod, _castInfo::castsource, _castInfo::casttarget, _dumpableObject::catId, COERCION_METHOD_BINARY, COERCION_METHOD_FUNCTION, COERCION_METHOD_INOUT, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _funcInfo::dobj, _castInfo::dobj, _dumpableObject::dump, dumpComment(), _dumpableObject::dumpId, _dumpableObject::ext_member, findFuncByOid(), findTypeByOid(), fmtId(), format_function_signature(), free, getFormattedTypeName(), _dumpableObject::name, NULL, OidIsValid, SECTION_PRE_DATA, selectSourceSchema(), write_msg(), and zeroAsNone.

Referenced by dumpDumpableObject().

{
    PQExpBuffer defqry;
    PQExpBuffer delqry;
    PQExpBuffer labelq;
    FuncInfo   *funcInfo = NULL;

    /* Skip if not to be dumped */
    if (!cast->dobj.dump || dataOnly)
        return;

    /* Cannot dump if we don't have the cast function's info */
    if (OidIsValid(cast->castfunc))
    {
        funcInfo = findFuncByOid(cast->castfunc);
        if (funcInfo == NULL)
            return;
    }

    /*
     * As per discussion we dump casts if one or more of the underlying
     * objects (the conversion function and the two data types) are not
     * builtin AND if all of the non-builtin objects are included in the dump.
     * Builtin meaning, the namespace name does not start with "pg_".
     *
     * However, for a cast that belongs to an extension, we must not use this
     * heuristic, but just dump the cast iff we're told to (via dobj.dump).
     */
    if (!cast->dobj.ext_member)
    {
        TypeInfo   *sourceInfo = findTypeByOid(cast->castsource);
        TypeInfo   *targetInfo = findTypeByOid(cast->casttarget);

        if (sourceInfo == NULL || targetInfo == NULL)
            return;

        /*
         * Skip this cast if all objects are from pg_
         */
        if ((funcInfo == NULL ||
             strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) == 0) &&
            strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) == 0 &&
            strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) == 0)
            return;

        /*
         * Skip cast if function isn't from pg_ and is not to be dumped.
         */
        if (funcInfo &&
            strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
            !funcInfo->dobj.dump)
            return;

        /*
         * Same for the source type
         */
        if (strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
            !sourceInfo->dobj.dump)
            return;

        /*
         * and the target type.
         */
        if (strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
            !targetInfo->dobj.dump)
            return;
    }

    /* Make sure we are in proper schema (needed for getFormattedTypeName) */
    selectSourceSchema(fout, "pg_catalog");

    defqry = createPQExpBuffer();
    delqry = createPQExpBuffer();
    labelq = createPQExpBuffer();

    appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
                    getFormattedTypeName(fout, cast->castsource, zeroAsNone),
                   getFormattedTypeName(fout, cast->casttarget, zeroAsNone));

    appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
                    getFormattedTypeName(fout, cast->castsource, zeroAsNone),
                   getFormattedTypeName(fout, cast->casttarget, zeroAsNone));

    switch (cast->castmethod)
    {
        case COERCION_METHOD_BINARY:
            appendPQExpBuffer(defqry, "WITHOUT FUNCTION");
            break;
        case COERCION_METHOD_INOUT:
            appendPQExpBuffer(defqry, "WITH INOUT");
            break;
        case COERCION_METHOD_FUNCTION:
            if (funcInfo)
            {
                char       *fsig = format_function_signature(fout, funcInfo, true);

                /*
                 * Always qualify the function name, in case it is not in
                 * pg_catalog schema (format_function_signature won't qualify
                 * it).
                 */
                appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
                           fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
                free(fsig);
            }
            else
                write_msg(NULL, "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n");
            break;
        default:
            write_msg(NULL, "WARNING: bogus value in pg_cast.castmethod field\n");
    }

    if (cast->castcontext == 'a')
        appendPQExpBuffer(defqry, " AS ASSIGNMENT");
    else if (cast->castcontext == 'i')
        appendPQExpBuffer(defqry, " AS IMPLICIT");
    appendPQExpBuffer(defqry, ";\n");

    appendPQExpBuffer(labelq, "CAST (%s AS %s)",
                    getFormattedTypeName(fout, cast->castsource, zeroAsNone),
                   getFormattedTypeName(fout, cast->casttarget, zeroAsNone));

    if (binary_upgrade)
        binary_upgrade_extension_member(defqry, &cast->dobj, labelq->data);

    ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
                 labelq->data,
                 "pg_catalog", NULL, "",
                 false, "CAST", SECTION_PRE_DATA,
                 defqry->data, delqry->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Cast Comments */
    dumpComment(fout, labelq->data,
                NULL, "",
                cast->dobj.catId, 0, cast->dobj.dumpId);

    destroyPQExpBuffer(defqry);
    destroyPQExpBuffer(delqry);
    destroyPQExpBuffer(labelq);
}

static void dumpCollation ( Archive fout,
CollInfo convinfo 
) [static]

Definition at line 11164 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _collInfo::dobj, _dumpableObject::dump, dumpComment(), _dumpableObject::dumpId, ExecuteSqlQueryForSingleRow(), fmtId(), _dumpableObject::name, NULL, CatalogId::oid, PQclear(), PQfnumber(), PQgetvalue(), _collInfo::rolname, SECTION_PRE_DATA, and selectSourceSchema().

Referenced by dumpDumpableObject().

{
    PQExpBuffer query;
    PQExpBuffer q;
    PQExpBuffer delq;
    PQExpBuffer labelq;
    PGresult   *res;
    int         i_collcollate;
    int         i_collctype;
    const char *collcollate;
    const char *collctype;

    /* Skip if not to be dumped */
    if (!collinfo->dobj.dump || dataOnly)
        return;

    query = createPQExpBuffer();
    q = createPQExpBuffer();
    delq = createPQExpBuffer();
    labelq = createPQExpBuffer();

    /* Make sure we are in proper schema */
    selectSourceSchema(fout, collinfo->dobj.namespace->dobj.name);

    /* Get conversion-specific details */
    appendPQExpBuffer(query, "SELECT "
                      "collcollate, "
                      "collctype "
                      "FROM pg_catalog.pg_collation c "
                      "WHERE c.oid = '%u'::pg_catalog.oid",
                      collinfo->dobj.catId.oid);

    res = ExecuteSqlQueryForSingleRow(fout, query->data);

    i_collcollate = PQfnumber(res, "collcollate");
    i_collctype = PQfnumber(res, "collctype");

    collcollate = PQgetvalue(res, 0, i_collcollate);
    collctype = PQgetvalue(res, 0, i_collctype);

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delq, "DROP COLLATION %s",
                      fmtId(collinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delq, ".%s;\n",
                      fmtId(collinfo->dobj.name));

    appendPQExpBuffer(q, "CREATE COLLATION %s (lc_collate = ",
                      fmtId(collinfo->dobj.name));
    appendStringLiteralAH(q, collcollate, fout);
    appendPQExpBuffer(q, ", lc_ctype = ");
    appendStringLiteralAH(q, collctype, fout);
    appendPQExpBuffer(q, ");\n");

    appendPQExpBuffer(labelq, "COLLATION %s", fmtId(collinfo->dobj.name));

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &collinfo->dobj, labelq->data);

    ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId,
                 collinfo->dobj.name,
                 collinfo->dobj.namespace->dobj.name,
                 NULL,
                 collinfo->rolname,
                 false, "COLLATION", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Collation Comments */
    dumpComment(fout, labelq->data,
                collinfo->dobj.namespace->dobj.name, collinfo->rolname,
                collinfo->dobj.catId, 0, collinfo->dobj.dumpId);

    PQclear(res);

    destroyPQExpBuffer(query);
    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
}

static void dumpComment ( Archive fout,
const char *  target,
const char *  namespace,
const char *  owner,
CatalogId  catalogId,
int  subid,
DumpId  dumpId 
) [static]

Definition at line 7322 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, dataOnly, CommentItem::descr, destroyPQExpBuffer(), findComments(), NULL, CommentItem::objsubid, CatalogId::oid, schemaOnly, SECTION_NONE, and CatalogId::tableoid.

Referenced by dumpAgg(), dumpBaseType(), dumpBlob(), dumpCast(), dumpCollation(), dumpCompositeType(), dumpConversion(), dumpDatabase(), dumpDomain(), dumpEnumType(), dumpEventTrigger(), dumpExtension(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpIndex(), dumpNamespace(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpProcLang(), dumpRangeType(), dumpRule(), dumpSequence(), dumpTableConstraintComment(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), and dumpTSTemplate().

{
    CommentItem *comments;
    int         ncomments;

    /* Comments are schema not data ... except blob comments are data */
    if (strncmp(target, "LARGE OBJECT ", 13) != 0)
    {
        if (dataOnly)
            return;
    }
    else
    {
        if (schemaOnly)
            return;
    }

    /* Search for comments associated with catalogId, using table */
    ncomments = findComments(fout, catalogId.tableoid, catalogId.oid,
                             &comments);

    /* Is there one matching the subid? */
    while (ncomments > 0)
    {
        if (comments->objsubid == subid)
            break;
        comments++;
        ncomments--;
    }

    /* If a comment exists, build COMMENT ON statement */
    if (ncomments > 0)
    {
        PQExpBuffer query = createPQExpBuffer();

        appendPQExpBuffer(query, "COMMENT ON %s IS ", target);
        appendStringLiteralAH(query, comments->descr, fout);
        appendPQExpBuffer(query, ";\n");

        /*
         * We mark comments as SECTION_NONE because they really belong in the
         * same section as their parent, whether that is pre-data or
         * post-data.
         */
        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                     target, namespace, NULL, owner,
                     false, "COMMENT", SECTION_NONE,
                     query->data, "", NULL,
                     &(dumpId), 1,
                     NULL, NULL);

        destroyPQExpBuffer(query);
    }
}

static void dumpCompositeType ( Archive fout,
TypeInfo tyinfo 
) [static]

Definition at line 8793 of file pg_dump.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ArchiveEntry(), atooid, binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_pg_class_oids(), binary_upgrade_set_type_oids_by_type_oid(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _collInfo::dobj, dumpACL(), dumpComment(), dumpCompositeTypeColComments(), dumpSecLabel(), ExecuteSqlQuery(), findCollationByOid(), fmtId(), i, _dumpableObject::name, NULL, OidIsValid, pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, SECTION_PRE_DATA, and selectSourceSchema().

Referenced by dumpType().

{
    PQExpBuffer q = createPQExpBuffer();
    PQExpBuffer dropped = createPQExpBuffer();
    PQExpBuffer delq = createPQExpBuffer();
    PQExpBuffer labelq = createPQExpBuffer();
    PQExpBuffer query = createPQExpBuffer();
    PGresult   *res;
    char       *qtypname;
    int         ntups;
    int         i_attname;
    int         i_atttypdefn;
    int         i_attlen;
    int         i_attalign;
    int         i_attisdropped;
    int         i_attcollation;
    int         i_typrelid;
    int         i;
    int         actual_atts;

    /* Set proper schema search path so type references list correctly */
    selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);

    /* Fetch type specific details */
    if (fout->remoteVersion >= 90100)
    {
        /*
         * attcollation is new in 9.1.  Since we only want to dump COLLATE
         * clauses for attributes whose collation is different from their
         * type's default, we use a CASE here to suppress uninteresting
         * attcollations cheaply.  atttypid will be 0 for dropped columns;
         * collation does not matter for those.
         */
        appendPQExpBuffer(query, "SELECT a.attname, "
            "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
                          "a.attlen, a.attalign, a.attisdropped, "
                          "CASE WHEN a.attcollation <> at.typcollation "
                          "THEN a.attcollation ELSE 0 END AS attcollation, "
                          "ct.typrelid "
                          "FROM pg_catalog.pg_type ct "
                "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
                    "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
                          "WHERE ct.oid = '%u'::pg_catalog.oid "
                          "ORDER BY a.attnum ",
                          tyinfo->dobj.catId.oid);
    }
    else
    {
        /*
         * We assume here that remoteVersion must be at least 70300.  Since
         * ALTER TYPE could not drop columns until 9.1, attisdropped should
         * always be false.
         */
        appendPQExpBuffer(query, "SELECT a.attname, "
            "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
                          "a.attlen, a.attalign, a.attisdropped, "
                          "0 AS attcollation, "
                          "ct.typrelid "
                     "FROM pg_catalog.pg_type ct, pg_catalog.pg_attribute a "
                          "WHERE ct.oid = '%u'::pg_catalog.oid "
                          "AND a.attrelid = ct.typrelid "
                          "ORDER BY a.attnum ",
                          tyinfo->dobj.catId.oid);
    }

    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    ntups = PQntuples(res);

    i_attname = PQfnumber(res, "attname");
    i_atttypdefn = PQfnumber(res, "atttypdefn");
    i_attlen = PQfnumber(res, "attlen");
    i_attalign = PQfnumber(res, "attalign");
    i_attisdropped = PQfnumber(res, "attisdropped");
    i_attcollation = PQfnumber(res, "attcollation");
    i_typrelid = PQfnumber(res, "typrelid");

    if (binary_upgrade)
    {
        Oid         typrelid = atooid(PQgetvalue(res, 0, i_typrelid));

        binary_upgrade_set_type_oids_by_type_oid(fout, q,
                                                 tyinfo->dobj.catId.oid);
        binary_upgrade_set_pg_class_oids(fout, q, typrelid, false);
    }

    qtypname = pg_strdup(fmtId(tyinfo->dobj.name));

    appendPQExpBuffer(q, "CREATE TYPE %s AS (",
                      qtypname);

    actual_atts = 0;
    for (i = 0; i < ntups; i++)
    {
        char       *attname;
        char       *atttypdefn;
        char       *attlen;
        char       *attalign;
        bool        attisdropped;
        Oid         attcollation;

        attname = PQgetvalue(res, i, i_attname);
        atttypdefn = PQgetvalue(res, i, i_atttypdefn);
        attlen = PQgetvalue(res, i, i_attlen);
        attalign = PQgetvalue(res, i, i_attalign);
        attisdropped = (PQgetvalue(res, i, i_attisdropped)[0] == 't');
        attcollation = atooid(PQgetvalue(res, i, i_attcollation));

        if (attisdropped && !binary_upgrade)
            continue;

        /* Format properly if not first attr */
        if (actual_atts++ > 0)
            appendPQExpBuffer(q, ",");
        appendPQExpBuffer(q, "\n\t");

        if (!attisdropped)
        {
            appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn);

            /* Add collation if not default for the column type */
            if (OidIsValid(attcollation))
            {
                CollInfo   *coll;

                coll = findCollationByOid(attcollation);
                if (coll)
                {
                    /* always schema-qualify, don't try to be smart */
                    appendPQExpBuffer(q, " COLLATE %s.",
                                      fmtId(coll->dobj.namespace->dobj.name));
                    appendPQExpBuffer(q, "%s",
                                      fmtId(coll->dobj.name));
                }
            }
        }
        else
        {
            /*
             * This is a dropped attribute and we're in binary_upgrade mode.
             * Insert a placeholder for it in the CREATE TYPE command, and set
             * length and alignment with direct UPDATE to the catalogs
             * afterwards. See similar code in dumpTableSchema().
             */
            appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname));

            /* stash separately for insertion after the CREATE TYPE */
            appendPQExpBuffer(dropped,
                      "\n-- For binary upgrade, recreate dropped column.\n");
            appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n"
                              "SET attlen = %s, "
                              "attalign = '%s', attbyval = false\n"
                              "WHERE attname = ", attlen, attalign);
            appendStringLiteralAH(dropped, attname, fout);
            appendPQExpBuffer(dropped, "\n  AND attrelid = ");
            appendStringLiteralAH(dropped, qtypname, fout);
            appendPQExpBuffer(dropped, "::pg_catalog.regclass;\n");

            appendPQExpBuffer(dropped, "ALTER TYPE %s ",
                              qtypname);
            appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
                              fmtId(attname));
        }
    }
    appendPQExpBuffer(q, "\n);\n");
    appendPQExpBufferStr(q, dropped->data);

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delq, "DROP TYPE %s.",
                      fmtId(tyinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delq, "%s;\n",
                      qtypname);

    appendPQExpBuffer(labelq, "TYPE %s", qtypname);

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);

    ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
                 tyinfo->dobj.name,
                 tyinfo->dobj.namespace->dobj.name,
                 NULL,
                 tyinfo->rolname, false,
                 "TYPE", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);


    /* Dump Type Comments and Security Labels */
    dumpComment(fout, labelq->data,
                tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
    dumpSecLabel(fout, labelq->data,
                 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);

    dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
            qtypname, NULL, tyinfo->dobj.name,
            tyinfo->dobj.namespace->dobj.name,
            tyinfo->rolname, tyinfo->typacl);

    PQclear(res);
    destroyPQExpBuffer(q);
    destroyPQExpBuffer(dropped);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
    destroyPQExpBuffer(query);

    /* Dump any per-column comments */
    dumpCompositeTypeColComments(fout, tyinfo);
}

static void dumpCompositeTypeColComments ( Archive fout,
TypeInfo tyinfo 
) [static]

Definition at line 9014 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), atooid, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, CommentItem::descr, destroyPQExpBuffer(), ExecuteSqlQuery(), findComments(), fmtId(), i, NULL, CommentItem::objsubid, PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), resetPQExpBuffer(), and SECTION_NONE.

Referenced by dumpCompositeType().

{
    CommentItem *comments;
    int         ncomments;
    PGresult   *res;
    PQExpBuffer query;
    PQExpBuffer target;
    Oid         pgClassOid;
    int         i;
    int         ntups;
    int         i_attname;
    int         i_attnum;

    query = createPQExpBuffer();

    /* We assume here that remoteVersion must be at least 70300 */
    appendPQExpBuffer(query,
                      "SELECT c.tableoid, a.attname, a.attnum "
                      "FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a "
                      "WHERE c.oid = '%u' AND c.oid = a.attrelid "
                      "  AND NOT a.attisdropped "
                      "ORDER BY a.attnum ",
                      tyinfo->typrelid);

    /* Fetch column attnames */
    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    ntups = PQntuples(res);
    if (ntups < 1)
    {
        PQclear(res);
        destroyPQExpBuffer(query);
        return;
    }

    pgClassOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "tableoid")));

    /* Search for comments associated with type's pg_class OID */
    ncomments = findComments(fout,
                             pgClassOid,
                             tyinfo->typrelid,
                             &comments);

    /* If no comments exist, we're done */
    if (ncomments <= 0)
    {
        PQclear(res);
        destroyPQExpBuffer(query);
        return;
    }

    /* Build COMMENT ON statements */
    target = createPQExpBuffer();

    i_attnum = PQfnumber(res, "attnum");
    i_attname = PQfnumber(res, "attname");
    while (ncomments > 0)
    {
        const char *attname;

        attname = NULL;
        for (i = 0; i < ntups; i++)
        {
            if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid)
            {
                attname = PQgetvalue(res, i, i_attname);
                break;
            }
        }
        if (attname)            /* just in case we don't find it */
        {
            const char *descr = comments->descr;

            resetPQExpBuffer(target);
            appendPQExpBuffer(target, "COLUMN %s.",
                              fmtId(tyinfo->dobj.name));
            appendPQExpBuffer(target, "%s",
                              fmtId(attname));

            resetPQExpBuffer(query);
            appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
            appendStringLiteralAH(query, descr, fout);
            appendPQExpBuffer(query, ";\n");

            ArchiveEntry(fout, nilCatalogId, createDumpId(),
                         target->data,
                         tyinfo->dobj.namespace->dobj.name,
                         NULL, tyinfo->rolname,
                         false, "COMMENT", SECTION_NONE,
                         query->data, "", NULL,
                         &(tyinfo->dobj.dumpId), 1,
                         NULL, NULL);
        }

        comments++;
        ncomments--;
    }

    PQclear(res);
    destroyPQExpBuffer(query);
    destroyPQExpBuffer(target);
}

static void dumpConstraint ( Archive fout,
ConstraintInfo coninfo 
) [static]

Definition at line 13542 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), binary_upgrade, binary_upgrade_set_pg_class_oids(), _dumpableObject::catId, _constraintInfo::condef, _constraintInfo::condeferrable, _constraintInfo::condeferred, _constraintInfo::condomain, _constraintInfo::conindex, _constraintInfo::contable, _constraintInfo::contype, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _indxInfo::dobj, _constraintInfo::dobj, _dumpableObject::dump, _dumpableObject::dumpId, dumpTableConstraintComment(), exit_horribly(), findObjectByDumpId(), fmtId(), getAttrName(), _indxInfo::indisclustered, _indxInfo::indkeys, _indxInfo::indnkeys, InvalidAttrNumber, _dumpableObject::name, NULL, CatalogId::oid, _indxInfo::options, _tableInfo::rolname, SECTION_POST_DATA, _constraintInfo::separate, and _indxInfo::tablespace.

Referenced by dumpDumpableObject().

{
    TableInfo  *tbinfo = coninfo->contable;
    PQExpBuffer q;
    PQExpBuffer delq;

    /* Skip if not to be dumped */
    if (!coninfo->dobj.dump || dataOnly)
        return;

    q = createPQExpBuffer();
    delq = createPQExpBuffer();

    if (coninfo->contype == 'p' ||
        coninfo->contype == 'u' ||
        coninfo->contype == 'x')
    {
        /* Index-related constraint */
        IndxInfo   *indxinfo;
        int         k;

        indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);

        if (indxinfo == NULL)
            exit_horribly(NULL, "missing index for constraint \"%s\"\n",
                          coninfo->dobj.name);

        if (binary_upgrade)
            binary_upgrade_set_pg_class_oids(fout, q,
                                             indxinfo->dobj.catId.oid, true);

        appendPQExpBuffer(q, "ALTER TABLE ONLY %s\n",
                          fmtId(tbinfo->dobj.name));
        appendPQExpBuffer(q, "    ADD CONSTRAINT %s ",
                          fmtId(coninfo->dobj.name));

        if (coninfo->condef)
        {
            /* pg_get_constraintdef should have provided everything */
            appendPQExpBuffer(q, "%s;\n", coninfo->condef);
        }
        else
        {
            appendPQExpBuffer(q, "%s (",
                         coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
            for (k = 0; k < indxinfo->indnkeys; k++)
            {
                int         indkey = (int) indxinfo->indkeys[k];
                const char *attname;

                if (indkey == InvalidAttrNumber)
                    break;
                attname = getAttrName(indkey, tbinfo);

                appendPQExpBuffer(q, "%s%s",
                                  (k == 0) ? "" : ", ",
                                  fmtId(attname));
            }

            appendPQExpBuffer(q, ")");

            if (indxinfo->options && strlen(indxinfo->options) > 0)
                appendPQExpBuffer(q, " WITH (%s)", indxinfo->options);

            if (coninfo->condeferrable)
            {
                appendPQExpBuffer(q, " DEFERRABLE");
                if (coninfo->condeferred)
                    appendPQExpBuffer(q, " INITIALLY DEFERRED");
            }

            appendPQExpBuffer(q, ";\n");
        }

        /* If the index is clustered, we need to record that. */
        if (indxinfo->indisclustered)
        {
            appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
                              fmtId(tbinfo->dobj.name));
            appendPQExpBuffer(q, " ON %s;\n",
                              fmtId(indxinfo->dobj.name));
        }

        /*
         * DROP must be fully qualified in case same name appears in
         * pg_catalog
         */
        appendPQExpBuffer(delq, "ALTER TABLE ONLY %s.",
                          fmtId(tbinfo->dobj.namespace->dobj.name));
        appendPQExpBuffer(delq, "%s ",
                          fmtId(tbinfo->dobj.name));
        appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
                          fmtId(coninfo->dobj.name));

        ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
                     coninfo->dobj.name,
                     tbinfo->dobj.namespace->dobj.name,
                     indxinfo->tablespace,
                     tbinfo->rolname, false,
                     "CONSTRAINT", SECTION_POST_DATA,
                     q->data, delq->data, NULL,
                     NULL, 0,
                     NULL, NULL);
    }
    else if (coninfo->contype == 'f')
    {
        /*
         * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that the
         * current table data is not processed
         */
        appendPQExpBuffer(q, "ALTER TABLE ONLY %s\n",
                          fmtId(tbinfo->dobj.name));
        appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
                          fmtId(coninfo->dobj.name),
                          coninfo->condef);

        /*
         * DROP must be fully qualified in case same name appears in
         * pg_catalog
         */
        appendPQExpBuffer(delq, "ALTER TABLE ONLY %s.",
                          fmtId(tbinfo->dobj.namespace->dobj.name));
        appendPQExpBuffer(delq, "%s ",
                          fmtId(tbinfo->dobj.name));
        appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
                          fmtId(coninfo->dobj.name));

        ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
                     coninfo->dobj.name,
                     tbinfo->dobj.namespace->dobj.name,
                     NULL,
                     tbinfo->rolname, false,
                     "FK CONSTRAINT", SECTION_POST_DATA,
                     q->data, delq->data, NULL,
                     NULL, 0,
                     NULL, NULL);
    }
    else if (coninfo->contype == 'c' && tbinfo)
    {
        /* CHECK constraint on a table */

        /* Ignore if not to be dumped separately */
        if (coninfo->separate)
        {
            /* not ONLY since we want it to propagate to children */
            appendPQExpBuffer(q, "ALTER TABLE %s\n",
                              fmtId(tbinfo->dobj.name));
            appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
                              fmtId(coninfo->dobj.name),
                              coninfo->condef);

            /*
             * DROP must be fully qualified in case same name appears in
             * pg_catalog
             */
            appendPQExpBuffer(delq, "ALTER TABLE %s.",
                              fmtId(tbinfo->dobj.namespace->dobj.name));
            appendPQExpBuffer(delq, "%s ",
                              fmtId(tbinfo->dobj.name));
            appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
                              fmtId(coninfo->dobj.name));

            ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
                         coninfo->dobj.name,
                         tbinfo->dobj.namespace->dobj.name,
                         NULL,
                         tbinfo->rolname, false,
                         "CHECK CONSTRAINT", SECTION_POST_DATA,
                         q->data, delq->data, NULL,
                         NULL, 0,
                         NULL, NULL);
        }
    }
    else if (coninfo->contype == 'c' && tbinfo == NULL)
    {
        /* CHECK constraint on a domain */
        TypeInfo   *tyinfo = coninfo->condomain;

        /* Ignore if not to be dumped separately */
        if (coninfo->separate)
        {
            appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
                              fmtId(tyinfo->dobj.name));
            appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
                              fmtId(coninfo->dobj.name),
                              coninfo->condef);

            /*
             * DROP must be fully qualified in case same name appears in
             * pg_catalog
             */
            appendPQExpBuffer(delq, "ALTER DOMAIN %s.",
                              fmtId(tyinfo->dobj.namespace->dobj.name));
            appendPQExpBuffer(delq, "%s ",
                              fmtId(tyinfo->dobj.name));
            appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
                              fmtId(coninfo->dobj.name));

            ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
                         coninfo->dobj.name,
                         tyinfo->dobj.namespace->dobj.name,
                         NULL,
                         tyinfo->rolname, false,
                         "CHECK CONSTRAINT", SECTION_POST_DATA,
                         q->data, delq->data, NULL,
                         NULL, 0,
                         NULL, NULL);
        }
    }
    else
    {
        exit_horribly(NULL, "unrecognized constraint type: %c\n",
                      coninfo->contype);
    }

    /* Dump Constraint Comments --- only works for table constraints */
    if (tbinfo && coninfo->separate)
        dumpTableConstraintComment(fout, coninfo);

    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
}

static void dumpConversion ( Archive fout,
ConvInfo convinfo 
) [static]

Definition at line 11252 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _convInfo::dobj, _dumpableObject::dump, dumpComment(), _dumpableObject::dumpId, ExecuteSqlQueryForSingleRow(), fmtId(), _dumpableObject::name, NULL, CatalogId::oid, PQclear(), PQfnumber(), PQgetvalue(), _convInfo::rolname, SECTION_PRE_DATA, and selectSourceSchema().

Referenced by dumpDumpableObject().

{
    PQExpBuffer query;
    PQExpBuffer q;
    PQExpBuffer delq;
    PQExpBuffer labelq;
    PGresult   *res;
    int         i_conforencoding;
    int         i_contoencoding;
    int         i_conproc;
    int         i_condefault;
    const char *conforencoding;
    const char *contoencoding;
    const char *conproc;
    bool        condefault;

    /* Skip if not to be dumped */
    if (!convinfo->dobj.dump || dataOnly)
        return;

    query = createPQExpBuffer();
    q = createPQExpBuffer();
    delq = createPQExpBuffer();
    labelq = createPQExpBuffer();

    /* Make sure we are in proper schema */
    selectSourceSchema(fout, convinfo->dobj.namespace->dobj.name);

    /* Get conversion-specific details */
    appendPQExpBuffer(query, "SELECT "
         "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
           "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
                      "conproc, condefault "
                      "FROM pg_catalog.pg_conversion c "
                      "WHERE c.oid = '%u'::pg_catalog.oid",
                      convinfo->dobj.catId.oid);

    res = ExecuteSqlQueryForSingleRow(fout, query->data);

    i_conforencoding = PQfnumber(res, "conforencoding");
    i_contoencoding = PQfnumber(res, "contoencoding");
    i_conproc = PQfnumber(res, "conproc");
    i_condefault = PQfnumber(res, "condefault");

    conforencoding = PQgetvalue(res, 0, i_conforencoding);
    contoencoding = PQgetvalue(res, 0, i_contoencoding);
    conproc = PQgetvalue(res, 0, i_conproc);
    condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delq, "DROP CONVERSION %s",
                      fmtId(convinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delq, ".%s;\n",
                      fmtId(convinfo->dobj.name));

    appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
                      (condefault) ? "DEFAULT " : "",
                      fmtId(convinfo->dobj.name));
    appendStringLiteralAH(q, conforencoding, fout);
    appendPQExpBuffer(q, " TO ");
    appendStringLiteralAH(q, contoencoding, fout);
    /* regproc is automatically quoted in 7.3 and above */
    appendPQExpBuffer(q, " FROM %s;\n", conproc);

    appendPQExpBuffer(labelq, "CONVERSION %s", fmtId(convinfo->dobj.name));

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &convinfo->dobj, labelq->data);

    ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
                 convinfo->dobj.name,
                 convinfo->dobj.namespace->dobj.name,
                 NULL,
                 convinfo->rolname,
                 false, "CONVERSION", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Conversion Comments */
    dumpComment(fout, labelq->data,
                convinfo->dobj.namespace->dobj.name, convinfo->rolname,
                convinfo->dobj.catId, 0, convinfo->dobj.dumpId);

    PQclear(res);

    destroyPQExpBuffer(query);
    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
}

static void dumpDatabase ( Archive AH  )  [static]

Definition at line 2107 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), atooid, binary_upgrade, buildShSecLabelQuery(), conn, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), dumpComment(), emitShSecLabels(), encoding, ExecuteSqlQuery(), ExecuteSqlQueryForSingleRow(), fmtId(), g_verbose, GetConnection(), LargeObjectMetadataRelationId, LargeObjectRelationId, no_security_labels, NULL, CatalogId::oid, PGRES_TUPLES_OK, PQclear(), PQdb(), PQfnumber(), PQgetvalue(), Archive::remoteVersion, resetPQExpBuffer(), SECTION_NONE, SECTION_PRE_DATA, selectSourceSchema(), CatalogId::tableoid, tablespace, username_subquery, and write_msg().

Referenced by main().

{
    PQExpBuffer dbQry = createPQExpBuffer();
    PQExpBuffer delQry = createPQExpBuffer();
    PQExpBuffer creaQry = createPQExpBuffer();
    PGconn     *conn = GetConnection(fout);
    PGresult   *res;
    int         i_tableoid,
                i_oid,
                i_dba,
                i_encoding,
                i_collate,
                i_ctype,
                i_frozenxid,
                i_tablespace;
    CatalogId   dbCatId;
    DumpId      dbDumpId;
    const char *datname,
               *dba,
               *encoding,
               *collate,
               *ctype,
               *tablespace;
    uint32      frozenxid;

    datname = PQdb(conn);

    if (g_verbose)
        write_msg(NULL, "saving database definition\n");

    /* Make sure we are in proper schema */
    selectSourceSchema(fout, "pg_catalog");

    /* Get the database owner and parameters from pg_database */
    if (fout->remoteVersion >= 80400)
    {
        appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                          "(%s datdba) AS dba, "
                          "pg_encoding_to_char(encoding) AS encoding, "
                          "datcollate, datctype, datfrozenxid, "
                          "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
                      "shobj_description(oid, 'pg_database') AS description "

                          "FROM pg_database "
                          "WHERE datname = ",
                          username_subquery);
        appendStringLiteralAH(dbQry, datname, fout);
    }
    else if (fout->remoteVersion >= 80200)
    {
        appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                          "(%s datdba) AS dba, "
                          "pg_encoding_to_char(encoding) AS encoding, "
                       "NULL AS datcollate, NULL AS datctype, datfrozenxid, "
                          "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
                      "shobj_description(oid, 'pg_database') AS description "

                          "FROM pg_database "
                          "WHERE datname = ",
                          username_subquery);
        appendStringLiteralAH(dbQry, datname, fout);
    }
    else if (fout->remoteVersion >= 80000)
    {
        appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                          "(%s datdba) AS dba, "
                          "pg_encoding_to_char(encoding) AS encoding, "
                       "NULL AS datcollate, NULL AS datctype, datfrozenxid, "
                          "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace "
                          "FROM pg_database "
                          "WHERE datname = ",
                          username_subquery);
        appendStringLiteralAH(dbQry, datname, fout);
    }
    else if (fout->remoteVersion >= 70100)
    {
        appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                          "(%s datdba) AS dba, "
                          "pg_encoding_to_char(encoding) AS encoding, "
                          "NULL AS datcollate, NULL AS datctype, "
                          "0 AS datfrozenxid, "
                          "NULL AS tablespace "
                          "FROM pg_database "
                          "WHERE datname = ",
                          username_subquery);
        appendStringLiteralAH(dbQry, datname, fout);
    }
    else
    {
        appendPQExpBuffer(dbQry, "SELECT "
                          "(SELECT oid FROM pg_class WHERE relname = 'pg_database') AS tableoid, "
                          "oid, "
                          "(%s datdba) AS dba, "
                          "pg_encoding_to_char(encoding) AS encoding, "
                          "NULL AS datcollate, NULL AS datctype, "
                          "0 AS datfrozenxid, "
                          "NULL AS tablespace "
                          "FROM pg_database "
                          "WHERE datname = ",
                          username_subquery);
        appendStringLiteralAH(dbQry, datname, fout);
    }

    res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);

    i_tableoid = PQfnumber(res, "tableoid");
    i_oid = PQfnumber(res, "oid");
    i_dba = PQfnumber(res, "dba");
    i_encoding = PQfnumber(res, "encoding");
    i_collate = PQfnumber(res, "datcollate");
    i_ctype = PQfnumber(res, "datctype");
    i_frozenxid = PQfnumber(res, "datfrozenxid");
    i_tablespace = PQfnumber(res, "tablespace");

    dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
    dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
    dba = PQgetvalue(res, 0, i_dba);
    encoding = PQgetvalue(res, 0, i_encoding);
    collate = PQgetvalue(res, 0, i_collate);
    ctype = PQgetvalue(res, 0, i_ctype);
    frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
    tablespace = PQgetvalue(res, 0, i_tablespace);

    appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
                      fmtId(datname));
    if (strlen(encoding) > 0)
    {
        appendPQExpBuffer(creaQry, " ENCODING = ");
        appendStringLiteralAH(creaQry, encoding, fout);
    }
    if (strlen(collate) > 0)
    {
        appendPQExpBuffer(creaQry, " LC_COLLATE = ");
        appendStringLiteralAH(creaQry, collate, fout);
    }
    if (strlen(ctype) > 0)
    {
        appendPQExpBuffer(creaQry, " LC_CTYPE = ");
        appendStringLiteralAH(creaQry, ctype, fout);
    }
    if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0)
        appendPQExpBuffer(creaQry, " TABLESPACE = %s",
                          fmtId(tablespace));
    appendPQExpBuffer(creaQry, ";\n");

    if (binary_upgrade)
    {
        appendPQExpBuffer(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n");
        appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
                          "SET datfrozenxid = '%u'\n"
                          "WHERE    datname = ",
                          frozenxid);
        appendStringLiteralAH(creaQry, datname, fout);
        appendPQExpBuffer(creaQry, ";\n");

    }

    appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
                      fmtId(datname));

    dbDumpId = createDumpId();

    ArchiveEntry(fout,
                 dbCatId,       /* catalog ID */
                 dbDumpId,      /* dump ID */
                 datname,       /* Name */
                 NULL,          /* Namespace */
                 NULL,          /* Tablespace */
                 dba,           /* Owner */
                 false,         /* with oids */
                 "DATABASE",    /* Desc */
                 SECTION_PRE_DATA,      /* Section */
                 creaQry->data, /* Create */
                 delQry->data,  /* Del */
                 NULL,          /* Copy */
                 NULL,          /* Deps */
                 0,             /* # Deps */
                 NULL,          /* Dumper */
                 NULL);         /* Dumper Arg */

    /*
     * pg_largeobject and pg_largeobject_metadata come from the old system
     * intact, so set their relfrozenxids.
     */
    if (binary_upgrade)
    {
        PGresult   *lo_res;
        PQExpBuffer loFrozenQry = createPQExpBuffer();
        PQExpBuffer loOutQry = createPQExpBuffer();
        int         i_relfrozenxid;

        /*
         * pg_largeobject
         */
        appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid\n"
                          "FROM pg_catalog.pg_class\n"
                          "WHERE oid = %u;\n",
                          LargeObjectRelationId);

        lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data);

        i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");

        appendPQExpBuffer(loOutQry, "\n-- For binary upgrade, set pg_largeobject.relfrozenxid\n");
        appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
                          "SET relfrozenxid = '%u'\n"
                          "WHERE oid = %u;\n",
                          atoi(PQgetvalue(lo_res, 0, i_relfrozenxid)),
                          LargeObjectRelationId);
        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                     "pg_largeobject", NULL, NULL, "",
                     false, "pg_largeobject", SECTION_PRE_DATA,
                     loOutQry->data, "", NULL,
                     NULL, 0,
                     NULL, NULL);

        PQclear(lo_res);

        /*
         * pg_largeobject_metadata
         */
        if (fout->remoteVersion >= 90000)
        {
            resetPQExpBuffer(loFrozenQry);
            resetPQExpBuffer(loOutQry);

            appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid\n"
                              "FROM pg_catalog.pg_class\n"
                              "WHERE oid = %u;\n",
                              LargeObjectMetadataRelationId);

            lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data);

            i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");

            appendPQExpBuffer(loOutQry, "\n-- For binary upgrade, set pg_largeobject_metadata.relfrozenxid\n");
            appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
                              "SET relfrozenxid = '%u'\n"
                              "WHERE oid = %u;\n",
                              atoi(PQgetvalue(lo_res, 0, i_relfrozenxid)),
                              LargeObjectMetadataRelationId);
            ArchiveEntry(fout, nilCatalogId, createDumpId(),
                         "pg_largeobject_metadata", NULL, NULL, "",
                         false, "pg_largeobject_metadata", SECTION_PRE_DATA,
                         loOutQry->data, "", NULL,
                         NULL, 0,
                         NULL, NULL);

            PQclear(lo_res);
        }

        destroyPQExpBuffer(loFrozenQry);
        destroyPQExpBuffer(loOutQry);
    }

    /* Dump DB comment if any */
    if (fout->remoteVersion >= 80200)
    {
        /*
         * 8.2 keeps comments on shared objects in a shared table, so we
         * cannot use the dumpComment used for other database objects.
         */
        char       *comment = PQgetvalue(res, 0, PQfnumber(res, "description"));

        if (comment && strlen(comment))
        {
            resetPQExpBuffer(dbQry);

            /*
             * Generates warning when loaded into a differently-named
             * database.
             */
            appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", fmtId(datname));
            appendStringLiteralAH(dbQry, comment, fout);
            appendPQExpBuffer(dbQry, ";\n");

            ArchiveEntry(fout, dbCatId, createDumpId(), datname, NULL, NULL,
                         dba, false, "COMMENT", SECTION_NONE,
                         dbQry->data, "", NULL,
                         &dbDumpId, 1, NULL, NULL);
        }
    }
    else
    {
        resetPQExpBuffer(dbQry);
        appendPQExpBuffer(dbQry, "DATABASE %s", fmtId(datname));
        dumpComment(fout, dbQry->data, NULL, "",
                    dbCatId, 0, dbDumpId);
    }

    PQclear(res);

    /* Dump shared security label. */
    if (!no_security_labels && fout->remoteVersion >= 90200)
    {
        PQExpBuffer seclabelQry = createPQExpBuffer();

        buildShSecLabelQuery(conn, "pg_database", dbCatId.oid, seclabelQry);
        res = ExecuteSqlQuery(fout, seclabelQry->data, PGRES_TUPLES_OK);
        resetPQExpBuffer(seclabelQry);
        emitShSecLabels(conn, res, seclabelQry, "DATABASE", datname);
        if (strlen(seclabelQry->data))
            ArchiveEntry(fout, dbCatId, createDumpId(), datname, NULL, NULL,
                         dba, false, "SECURITY LABEL", SECTION_NONE,
                         seclabelQry->data, "", NULL,
                         &dbDumpId, 1, NULL, NULL);
        destroyPQExpBuffer(seclabelQry);
    }

    destroyPQExpBuffer(dbQry);
    destroyPQExpBuffer(delQry);
    destroyPQExpBuffer(creaQry);
}

static void dumpDefaultACL ( Archive fout,
DefaultACLInfo daclinfo 
) [static]

Definition at line 12244 of file pg_dump.c.

References aclsSkip, appendPQExpBuffer(), ArchiveEntry(), buildDefaultACLCommands(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, _defaultACLInfo::defaclacl, DEFACLOBJ_FUNCTION, DEFACLOBJ_RELATION, DEFACLOBJ_SEQUENCE, DEFACLOBJ_TYPE, _defaultACLInfo::defaclobjtype, _defaultACLInfo::defaclrole, destroyPQExpBuffer(), _defaultACLInfo::dobj, _dumpableObject::dump, _dumpableObject::dumpId, exit_horribly(), _dumpableObject::name, NULL, Archive::remoteVersion, and SECTION_POST_DATA.

Referenced by dumpDumpableObject().

{
    PQExpBuffer q;
    PQExpBuffer tag;
    const char *type;

    /* Skip if not to be dumped */
    if (!daclinfo->dobj.dump || dataOnly || aclsSkip)
        return;

    q = createPQExpBuffer();
    tag = createPQExpBuffer();

    switch (daclinfo->defaclobjtype)
    {
        case DEFACLOBJ_RELATION:
            type = "TABLES";
            break;
        case DEFACLOBJ_SEQUENCE:
            type = "SEQUENCES";
            break;
        case DEFACLOBJ_FUNCTION:
            type = "FUNCTIONS";
            break;
        case DEFACLOBJ_TYPE:
            type = "TYPES";
            break;
        default:
            /* shouldn't get here */
            exit_horribly(NULL,
                      "unrecognized object type in default privileges: %d\n",
                          (int) daclinfo->defaclobjtype);
            type = "";          /* keep compiler quiet */
    }

    appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);

    /* build the actual command(s) for this tuple */
    if (!buildDefaultACLCommands(type,
                                 daclinfo->dobj.namespace != NULL ?
                                 daclinfo->dobj.namespace->dobj.name : NULL,
                                 daclinfo->defaclacl,
                                 daclinfo->defaclrole,
                                 fout->remoteVersion,
                                 q))
        exit_horribly(NULL, "could not parse default ACL list (%s)\n",
                      daclinfo->defaclacl);

    ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
                 tag->data,
       daclinfo->dobj.namespace ? daclinfo->dobj.namespace->dobj.name : NULL,
                 NULL,
                 daclinfo->defaclrole,
                 false, "DEFAULT ACL", SECTION_POST_DATA,
                 q->data, "", NULL,
                 NULL, 0,
                 NULL, NULL);

    destroyPQExpBuffer(tag);
    destroyPQExpBuffer(q);
}

static void dumpDomain ( Archive fout,
TypeInfo tyinfo 
) [static]

Definition at line 8630 of file pg_dump.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, ArchiveEntry(), atooid, binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_type_oids_by_type_oid(), _constraintInfo::condef, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _constraintInfo::dobj, _collInfo::dobj, dumpACL(), dumpComment(), dumpSecLabel(), ExecuteSqlQueryForSingleRow(), findCollationByOid(), fmtId(), i, _dumpableObject::name, NULL, OidIsValid, pg_strdup(), PQclear(), PQfnumber(), PQgetisnull(), PQgetvalue(), Archive::remoteVersion, SECTION_PRE_DATA, selectSourceSchema(), and _constraintInfo::separate.

Referenced by dumpType().

{
    PQExpBuffer q = createPQExpBuffer();
    PQExpBuffer delq = createPQExpBuffer();
    PQExpBuffer labelq = createPQExpBuffer();
    PQExpBuffer query = createPQExpBuffer();
    PGresult   *res;
    int         i;
    char       *qtypname;
    char       *typnotnull;
    char       *typdefn;
    char       *typdefault;
    Oid         typcollation;
    bool        typdefault_is_literal = false;

    /* Set proper schema search path so type references list correctly */
    selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);

    /* Fetch domain specific details */
    if (fout->remoteVersion >= 90100)
    {
        /* typcollation is new in 9.1 */
        appendPQExpBuffer(query, "SELECT t.typnotnull, "
            "pg_catalog.format_type(t.typbasetype, t.typtypmod) AS typdefn, "
                          "pg_catalog.pg_get_expr(t.typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
                          "t.typdefault, "
                          "CASE WHEN t.typcollation <> u.typcollation "
                          "THEN t.typcollation ELSE 0 END AS typcollation "
                          "FROM pg_catalog.pg_type t "
                 "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
                          "WHERE t.oid = '%u'::pg_catalog.oid",
                          tyinfo->dobj.catId.oid);
    }
    else
    {
        /* We assume here that remoteVersion must be at least 70300 */
        appendPQExpBuffer(query, "SELECT typnotnull, "
                "pg_catalog.format_type(typbasetype, typtypmod) AS typdefn, "
                          "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
                          "typdefault, 0 AS typcollation "
                          "FROM pg_catalog.pg_type "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          tyinfo->dobj.catId.oid);
    }

    res = ExecuteSqlQueryForSingleRow(fout, query->data);

    typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
    typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
    if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
        typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
    else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
    {
        typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
        typdefault_is_literal = true;   /* it needs quotes */
    }
    else
        typdefault = NULL;
    typcollation = atooid(PQgetvalue(res, 0, PQfnumber(res, "typcollation")));

    if (binary_upgrade)
        binary_upgrade_set_type_oids_by_type_oid(fout, q,
                                                 tyinfo->dobj.catId.oid);

    qtypname = pg_strdup(fmtId(tyinfo->dobj.name));

    appendPQExpBuffer(q,
                      "CREATE DOMAIN %s AS %s",
                      qtypname,
                      typdefn);

    /* Print collation only if different from base type's collation */
    if (OidIsValid(typcollation))
    {
        CollInfo   *coll;

        coll = findCollationByOid(typcollation);
        if (coll)
        {
            /* always schema-qualify, don't try to be smart */
            appendPQExpBuffer(q, " COLLATE %s.",
                              fmtId(coll->dobj.namespace->dobj.name));
            appendPQExpBuffer(q, "%s",
                              fmtId(coll->dobj.name));
        }
    }

    if (typnotnull[0] == 't')
        appendPQExpBuffer(q, " NOT NULL");

    if (typdefault != NULL)
    {
        appendPQExpBuffer(q, " DEFAULT ");
        if (typdefault_is_literal)
            appendStringLiteralAH(q, typdefault, fout);
        else
            appendPQExpBufferStr(q, typdefault);
    }

    PQclear(res);

    /*
     * Add any CHECK constraints for the domain
     */
    for (i = 0; i < tyinfo->nDomChecks; i++)
    {
        ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);

        if (!domcheck->separate)
            appendPQExpBuffer(q, "\n\tCONSTRAINT %s %s",
                              fmtId(domcheck->dobj.name), domcheck->condef);
    }

    appendPQExpBuffer(q, ";\n");

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delq, "DROP DOMAIN %s.",
                      fmtId(tyinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delq, "%s;\n",
                      qtypname);

    appendPQExpBuffer(labelq, "DOMAIN %s", qtypname);

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);

    ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
                 tyinfo->dobj.name,
                 tyinfo->dobj.namespace->dobj.name,
                 NULL,
                 tyinfo->rolname, false,
                 "DOMAIN", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Domain Comments and Security Labels */
    dumpComment(fout, labelq->data,
                tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
    dumpSecLabel(fout, labelq->data,
                 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);

    dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
            qtypname, NULL, tyinfo->dobj.name,
            tyinfo->dobj.namespace->dobj.name,
            tyinfo->rolname, tyinfo->typacl);

    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
    destroyPQExpBuffer(query);
}

static void dumpDumpableObject ( Archive fout,
DumpableObject dobj 
) [static]

Definition at line 7641 of file pg_dump.c.

References ArchiveEntry(), DO_AGG, DO_ATTRDEF, DO_BLOB, DO_BLOB_DATA, DO_CAST, DO_COLLATION, DO_CONSTRAINT, DO_CONVERSION, DO_DEFAULT_ACL, DO_DUMMY_TYPE, DO_EVENT_TRIGGER, DO_EXTENSION, DO_FDW, DO_FK_CONSTRAINT, DO_FOREIGN_SERVER, DO_FUNC, DO_INDEX, DO_NAMESPACE, DO_OPCLASS, DO_OPERATOR, DO_OPFAMILY, DO_POST_DATA_BOUNDARY, DO_PRE_DATA_BOUNDARY, DO_PROCLANG, DO_REFRESH_MATVIEW, DO_RULE, DO_SHELL_TYPE, DO_TABLE, DO_TABLE_DATA, DO_TRIGGER, DO_TSCONFIG, DO_TSDICT, DO_TSPARSER, DO_TSTEMPLATE, DO_TYPE, dumpAgg(), dumpAttrDef(), dumpBlob(), dumpBlobs(), dumpCast(), dumpCollation(), dumpConstraint(), dumpConversion(), dumpDefaultACL(), dumpEventTrigger(), dumpExtension(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpIndex(), dumpNamespace(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpProcLang(), dumpRule(), dumpSequenceData(), dumpShellType(), dumpTable(), dumpTableData(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), dumpType(), NULL, _dumpableObject::objType, refreshMatViewData(), RELKIND_SEQUENCE, and SECTION_DATA.

Referenced by main().

{
    switch (dobj->objType)
    {
        case DO_NAMESPACE:
            dumpNamespace(fout, (NamespaceInfo *) dobj);
            break;
        case DO_EXTENSION:
            dumpExtension(fout, (ExtensionInfo *) dobj);
            break;
        case DO_TYPE:
            dumpType(fout, (TypeInfo *) dobj);
            break;
        case DO_SHELL_TYPE:
            dumpShellType(fout, (ShellTypeInfo *) dobj);
            break;
        case DO_FUNC:
            dumpFunc(fout, (FuncInfo *) dobj);
            break;
        case DO_AGG:
            dumpAgg(fout, (AggInfo *) dobj);
            break;
        case DO_OPERATOR:
            dumpOpr(fout, (OprInfo *) dobj);
            break;
        case DO_OPCLASS:
            dumpOpclass(fout, (OpclassInfo *) dobj);
            break;
        case DO_OPFAMILY:
            dumpOpfamily(fout, (OpfamilyInfo *) dobj);
            break;
        case DO_COLLATION:
            dumpCollation(fout, (CollInfo *) dobj);
            break;
        case DO_CONVERSION:
            dumpConversion(fout, (ConvInfo *) dobj);
            break;
        case DO_TABLE:
            dumpTable(fout, (TableInfo *) dobj);
            break;
        case DO_ATTRDEF:
            dumpAttrDef(fout, (AttrDefInfo *) dobj);
            break;
        case DO_INDEX:
            dumpIndex(fout, (IndxInfo *) dobj);
            break;
        case DO_REFRESH_MATVIEW:
            refreshMatViewData(fout, (TableDataInfo *) dobj);
            break;
        case DO_RULE:
            dumpRule(fout, (RuleInfo *) dobj);
            break;
        case DO_TRIGGER:
            dumpTrigger(fout, (TriggerInfo *) dobj);
            break;
        case DO_EVENT_TRIGGER:
            dumpEventTrigger(fout, (EventTriggerInfo *) dobj);
            break;
        case DO_CONSTRAINT:
            dumpConstraint(fout, (ConstraintInfo *) dobj);
            break;
        case DO_FK_CONSTRAINT:
            dumpConstraint(fout, (ConstraintInfo *) dobj);
            break;
        case DO_PROCLANG:
            dumpProcLang(fout, (ProcLangInfo *) dobj);
            break;
        case DO_CAST:
            dumpCast(fout, (CastInfo *) dobj);
            break;
        case DO_TABLE_DATA:
            if (((TableDataInfo *) dobj)->tdtable->relkind == RELKIND_SEQUENCE)
                dumpSequenceData(fout, (TableDataInfo *) dobj);
            else
                dumpTableData(fout, (TableDataInfo *) dobj);
            break;
        case DO_DUMMY_TYPE:
            /* table rowtypes and array types are never dumped separately */
            break;
        case DO_TSPARSER:
            dumpTSParser(fout, (TSParserInfo *) dobj);
            break;
        case DO_TSDICT:
            dumpTSDictionary(fout, (TSDictInfo *) dobj);
            break;
        case DO_TSTEMPLATE:
            dumpTSTemplate(fout, (TSTemplateInfo *) dobj);
            break;
        case DO_TSCONFIG:
            dumpTSConfig(fout, (TSConfigInfo *) dobj);
            break;
        case DO_FDW:
            dumpForeignDataWrapper(fout, (FdwInfo *) dobj);
            break;
        case DO_FOREIGN_SERVER:
            dumpForeignServer(fout, (ForeignServerInfo *) dobj);
            break;
        case DO_DEFAULT_ACL:
            dumpDefaultACL(fout, (DefaultACLInfo *) dobj);
            break;
        case DO_BLOB:
            dumpBlob(fout, (BlobInfo *) dobj);
            break;
        case DO_BLOB_DATA:
            ArchiveEntry(fout, dobj->catId, dobj->dumpId,
                         dobj->name, NULL, NULL, "",
                         false, "BLOBS", SECTION_DATA,
                         "", "", NULL,
                         NULL, 0,
                         dumpBlobs, NULL);
            break;
        case DO_PRE_DATA_BOUNDARY:
        case DO_POST_DATA_BOUNDARY:
            /* never dumped, nothing to do */
            break;
    }
}

static void dumpEncoding ( Archive AH  )  [static]

Definition at line 2426 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), Archive::encoding, g_verbose, NULL, pg_encoding_to_char(), SECTION_PRE_DATA, and write_msg().

Referenced by main().

{
    const char *encname = pg_encoding_to_char(AH->encoding);
    PQExpBuffer qry = createPQExpBuffer();

    if (g_verbose)
        write_msg(NULL, "saving encoding = %s\n", encname);

    appendPQExpBuffer(qry, "SET client_encoding = ");
    appendStringLiteralAH(qry, encname, AH);
    appendPQExpBuffer(qry, ";\n");

    ArchiveEntry(AH, nilCatalogId, createDumpId(),
                 "ENCODING", NULL, NULL, "",
                 false, "ENCODING", SECTION_PRE_DATA,
                 qry->data, "", NULL,
                 NULL, 0,
                 NULL, NULL);

    destroyPQExpBuffer(qry);
}

static void dumpEnumType ( Archive fout,
TypeInfo tyinfo 
) [static]

Definition at line 7978 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), atooid, binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_type_oids_by_type_oid(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), dumpACL(), dumpComment(), dumpSecLabel(), ExecuteSqlQuery(), fmtId(), i, label, NULL, pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, SECTION_PRE_DATA, and selectSourceSchema().

Referenced by dumpType().

{
    PQExpBuffer q = createPQExpBuffer();
    PQExpBuffer delq = createPQExpBuffer();
    PQExpBuffer labelq = createPQExpBuffer();
    PQExpBuffer query = createPQExpBuffer();
    PGresult   *res;
    int         num,
                i;
    Oid         enum_oid;
    char       *qtypname;
    char       *label;

    /* Set proper schema search path */
    selectSourceSchema(fout, "pg_catalog");

    if (fout->remoteVersion >= 90100)
        appendPQExpBuffer(query, "SELECT oid, enumlabel "
                          "FROM pg_catalog.pg_enum "
                          "WHERE enumtypid = '%u'"
                          "ORDER BY enumsortorder",
                          tyinfo->dobj.catId.oid);
    else
        appendPQExpBuffer(query, "SELECT oid, enumlabel "
                          "FROM pg_catalog.pg_enum "
                          "WHERE enumtypid = '%u'"
                          "ORDER BY oid",
                          tyinfo->dobj.catId.oid);

    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    num = PQntuples(res);

    qtypname = pg_strdup(fmtId(tyinfo->dobj.name));

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog.
     * CASCADE shouldn't be required here as for normal types since the I/O
     * functions are generic and do not get dropped.
     */
    appendPQExpBuffer(delq, "DROP TYPE %s.",
                      fmtId(tyinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delq, "%s;\n",
                      qtypname);

    if (binary_upgrade)
        binary_upgrade_set_type_oids_by_type_oid(fout, q,
                                                 tyinfo->dobj.catId.oid);

    appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
                      qtypname);

    if (!binary_upgrade)
    {
        /* Labels with server-assigned oids */
        for (i = 0; i < num; i++)
        {
            label = PQgetvalue(res, i, PQfnumber(res, "enumlabel"));
            if (i > 0)
                appendPQExpBuffer(q, ",");
            appendPQExpBuffer(q, "\n    ");
            appendStringLiteralAH(q, label, fout);
        }
    }

    appendPQExpBuffer(q, "\n);\n");

    if (binary_upgrade)
    {
        /* Labels with dump-assigned (preserved) oids */
        for (i = 0; i < num; i++)
        {
            enum_oid = atooid(PQgetvalue(res, i, PQfnumber(res, "oid")));
            label = PQgetvalue(res, i, PQfnumber(res, "enumlabel"));

            if (i == 0)
                appendPQExpBuffer(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
            appendPQExpBuffer(q,
                              "SELECT binary_upgrade.set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
                              enum_oid);
            appendPQExpBuffer(q, "ALTER TYPE %s.",
                              fmtId(tyinfo->dobj.namespace->dobj.name));
            appendPQExpBuffer(q, "%s ADD VALUE ",
                              qtypname);
            appendStringLiteralAH(q, label, fout);
            appendPQExpBuffer(q, ";\n\n");
        }
    }

    appendPQExpBuffer(labelq, "TYPE %s", qtypname);

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);

    ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
                 tyinfo->dobj.name,
                 tyinfo->dobj.namespace->dobj.name,
                 NULL,
                 tyinfo->rolname, false,
                 "TYPE", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Type Comments and Security Labels */
    dumpComment(fout, labelq->data,
                tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
    dumpSecLabel(fout, labelq->data,
                 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);

    dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
            qtypname, NULL, tyinfo->dobj.name,
            tyinfo->dobj.namespace->dobj.name,
            tyinfo->rolname, tyinfo->typacl);

    PQclear(res);
    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
    destroyPQExpBuffer(query);
}

static void dumpEventTrigger ( Archive fout,
EventTriggerInfo evtinfo 
) [static]

Definition at line 14300 of file pg_dump.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _evttriggerInfo::dobj, dumpComment(), _dumpableObject::dumpId, _evttriggerInfo::evtenabled, _evttriggerInfo::evtevent, _evttriggerInfo::evtfname, _evttriggerInfo::evtowner, _evttriggerInfo::evttags, fmtId(), _dumpableObject::name, NULL, and SECTION_POST_DATA.

Referenced by dumpDumpableObject().

{
    PQExpBuffer query;
    PQExpBuffer labelq;

    query = createPQExpBuffer();
    labelq = createPQExpBuffer();

    appendPQExpBuffer(query, "CREATE EVENT TRIGGER ");
    appendPQExpBufferStr(query, fmtId(evtinfo->dobj.name));
    appendPQExpBuffer(query, " ON ");
    appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
    appendPQExpBufferStr(query, " ");

    if (strcmp("", evtinfo->evttags) != 0)
    {
        appendPQExpBufferStr(query, "\n         WHEN TAG IN (");
        appendPQExpBufferStr(query, evtinfo->evttags);
        appendPQExpBufferStr(query, ") ");
    }

    appendPQExpBuffer(query, "\n   EXECUTE PROCEDURE ");
    appendPQExpBufferStr(query, evtinfo->evtfname);
    appendPQExpBuffer(query, "();\n");

    if (evtinfo->evtenabled != 'O')
    {
        appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
                          fmtId(evtinfo->dobj.name));
        switch (evtinfo->evtenabled)
        {
            case 'D':
                appendPQExpBuffer(query, "DISABLE");
                break;
            case 'A':
                appendPQExpBuffer(query, "ENABLE ALWAYS");
                break;
            case 'R':
                appendPQExpBuffer(query, "ENABLE REPLICA");
                break;
            default:
                appendPQExpBuffer(query, "ENABLE");
                break;
        }
        appendPQExpBuffer(query, ";\n");
    }
    appendPQExpBuffer(labelq, "EVENT TRIGGER %s ",
                      fmtId(evtinfo->dobj.name));

    ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
                 evtinfo->dobj.name, NULL, NULL, evtinfo->evtowner, false,
                 "EVENT TRIGGER", SECTION_POST_DATA,
                 query->data, "", NULL, NULL, 0, NULL, NULL);

    dumpComment(fout, labelq->data,
                NULL, NULL,
                evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);

    destroyPQExpBuffer(query);
    destroyPQExpBuffer(labelq);
}

static void dumpExtension ( Archive fout,
ExtensionInfo extinfo 
) [static]

Definition at line 7827 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), binary_upgrade, _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, _dumpableObject::dependencies, destroyPQExpBuffer(), DO_EXTENSION, _extensionInfo::dobj, _dumpableObject::dump, dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), _extensionInfo::extcondition, _extensionInfo::extconfig, _extensionInfo::extversion, findObjectByDumpId(), fmtId(), free, i, _dumpableObject::name, _dumpableObject::nDeps, NULL, _dumpableObject::objType, pg_strdup(), _extensionInfo::relocatable, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

{
    PQExpBuffer q;
    PQExpBuffer delq;
    PQExpBuffer labelq;
    char       *qextname;

    /* Skip if not to be dumped */
    if (!extinfo->dobj.dump || dataOnly)
        return;

    q = createPQExpBuffer();
    delq = createPQExpBuffer();
    labelq = createPQExpBuffer();

    qextname = pg_strdup(fmtId(extinfo->dobj.name));

    appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);

    if (!binary_upgrade)
    {
        /*
         * In a regular dump, we use IF NOT EXISTS so that there isn't a
         * problem if the extension already exists in the target database;
         * this is essential for installed-by-default extensions such as
         * plpgsql.
         *
         * In binary-upgrade mode, that doesn't work well, so instead we skip
         * built-in extensions based on their OIDs; see
         * selectDumpableExtension.
         */
        appendPQExpBuffer(q, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s;\n",
                          qextname, fmtId(extinfo->namespace));
    }
    else
    {
        int         i;
        int         n;

        appendPQExpBuffer(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");

        /*
         * We unconditionally create the extension, so we must drop it if it
         * exists.  This could happen if the user deleted 'plpgsql' and then
         * readded it, causing its oid to be greater than FirstNormalObjectId.
         * The FirstNormalObjectId test was kept to avoid repeatedly dropping
         * and recreating extensions like 'plpgsql'.
         */
        appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname);

        appendPQExpBuffer(q,
                          "SELECT binary_upgrade.create_empty_extension(");
        appendStringLiteralAH(q, extinfo->dobj.name, fout);
        appendPQExpBuffer(q, ", ");
        appendStringLiteralAH(q, extinfo->namespace, fout);
        appendPQExpBuffer(q, ", ");
        appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
        appendStringLiteralAH(q, extinfo->extversion, fout);
        appendPQExpBuffer(q, ", ");

        /*
         * Note that we're pushing extconfig (an OID array) back into
         * pg_extension exactly as-is.  This is OK because pg_class OIDs are
         * preserved in binary upgrade.
         */
        if (strlen(extinfo->extconfig) > 2)
            appendStringLiteralAH(q, extinfo->extconfig, fout);
        else
            appendPQExpBuffer(q, "NULL");
        appendPQExpBuffer(q, ", ");
        if (strlen(extinfo->extcondition) > 2)
            appendStringLiteralAH(q, extinfo->extcondition, fout);
        else
            appendPQExpBuffer(q, "NULL");
        appendPQExpBuffer(q, ", ");
        appendPQExpBuffer(q, "ARRAY[");
        n = 0;
        for (i = 0; i < extinfo->dobj.nDeps; i++)
        {
            DumpableObject *extobj;

            extobj = findObjectByDumpId(extinfo->dobj.dependencies[i]);
            if (extobj && extobj->objType == DO_EXTENSION)
            {
                if (n++ > 0)
                    appendPQExpBuffer(q, ",");
                appendStringLiteralAH(q, extobj->name, fout);
            }
        }
        appendPQExpBuffer(q, "]::pg_catalog.text[]");
        appendPQExpBuffer(q, ");\n");
    }

    appendPQExpBuffer(labelq, "EXTENSION %s", qextname);

    ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
                 extinfo->dobj.name,
                 NULL, NULL,
                 "",
                 false, "EXTENSION", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Extension Comments and Security Labels */
    dumpComment(fout, labelq->data,
                NULL, "",
                extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
    dumpSecLabel(fout, labelq->data,
                 NULL, "",
                 extinfo->dobj.catId, 0, extinfo->dobj.dumpId);

    free(qextname);

    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
}

static void dumpForeignDataWrapper ( Archive fout,
FdwInfo fdwinfo 
) [static]

Definition at line 11965 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _fdwInfo::dobj, _dumpableObject::dump, dumpACL(), dumpComment(), _dumpableObject::dumpId, _dumpableObject::ext_member, _fdwInfo::fdwacl, _fdwInfo::fdwhandler, _fdwInfo::fdwoptions, _fdwInfo::fdwvalidator, fmtId(), free, include_everything, _dumpableObject::name, NULL, pg_strdup(), _fdwInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

{
    PQExpBuffer q;
    PQExpBuffer delq;
    PQExpBuffer labelq;
    char       *qfdwname;

    /* Skip if not to be dumped */
    if (!fdwinfo->dobj.dump || dataOnly)
        return;

    /*
     * FDWs that belong to an extension are dumped based on their "dump"
     * field. Otherwise omit them if we are only dumping some specific object.
     */
    if (!fdwinfo->dobj.ext_member)
        if (!include_everything)
            return;

    q = createPQExpBuffer();
    delq = createPQExpBuffer();
    labelq = createPQExpBuffer();

    qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));

    appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
                      qfdwname);

    if (strcmp(fdwinfo->fdwhandler, "-") != 0)
        appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);

    if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
        appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);

    if (strlen(fdwinfo->fdwoptions) > 0)
        appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", fdwinfo->fdwoptions);

    appendPQExpBuffer(q, ";\n");

    appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
                      qfdwname);

    appendPQExpBuffer(labelq, "FOREIGN DATA WRAPPER %s",
                      qfdwname);

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &fdwinfo->dobj, labelq->data);

    ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
                 fdwinfo->dobj.name,
                 NULL,
                 NULL,
                 fdwinfo->rolname,
                 false, "FOREIGN DATA WRAPPER", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Handle the ACL */
    dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
            "FOREIGN DATA WRAPPER",
            qfdwname, NULL, fdwinfo->dobj.name,
            NULL, fdwinfo->rolname,
            fdwinfo->fdwacl);

    /* Dump Foreign Data Wrapper Comments */
    dumpComment(fout, labelq->data,
                NULL, fdwinfo->rolname,
                fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);

    free(qfdwname);

    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
}

static void dumpForeignServer ( Archive fout,
ForeignServerInfo srvinfo 
) [static]

Definition at line 12047 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _foreignServerInfo::dobj, _dumpableObject::dump, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpUserMappings(), ExecuteSqlQueryForSingleRow(), fmtId(), free, include_everything, _dumpableObject::name, NULL, pg_strdup(), PQgetvalue(), _foreignServerInfo::rolname, SECTION_PRE_DATA, selectSourceSchema(), _foreignServerInfo::srvacl, _foreignServerInfo::srvfdw, _foreignServerInfo::srvoptions, _foreignServerInfo::srvtype, and _foreignServerInfo::srvversion.

Referenced by dumpDumpableObject().

{
    PQExpBuffer q;
    PQExpBuffer delq;
    PQExpBuffer labelq;
    PQExpBuffer query;
    PGresult   *res;
    char       *qsrvname;
    char       *fdwname;

    /* Skip if not to be dumped */
    if (!srvinfo->dobj.dump || dataOnly || !include_everything)
        return;

    q = createPQExpBuffer();
    delq = createPQExpBuffer();
    labelq = createPQExpBuffer();
    query = createPQExpBuffer();

    qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));

    /* look up the foreign-data wrapper */
    selectSourceSchema(fout, "pg_catalog");
    appendPQExpBuffer(query, "SELECT fdwname "
                      "FROM pg_foreign_data_wrapper w "
                      "WHERE w.oid = '%u'",
                      srvinfo->srvfdw);
    res = ExecuteSqlQueryForSingleRow(fout, query->data);
    fdwname = PQgetvalue(res, 0, 0);

    appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
    if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
    {
        appendPQExpBuffer(q, " TYPE ");
        appendStringLiteralAH(q, srvinfo->srvtype, fout);
    }
    if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
    {
        appendPQExpBuffer(q, " VERSION ");
        appendStringLiteralAH(q, srvinfo->srvversion, fout);
    }

    appendPQExpBuffer(q, " FOREIGN DATA WRAPPER ");
    appendPQExpBuffer(q, "%s", fmtId(fdwname));

    if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
        appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", srvinfo->srvoptions);

    appendPQExpBuffer(q, ";\n");

    appendPQExpBuffer(delq, "DROP SERVER %s;\n",
                      qsrvname);

    appendPQExpBuffer(labelq, "SERVER %s", qsrvname);

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &srvinfo->dobj, labelq->data);

    ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
                 srvinfo->dobj.name,
                 NULL,
                 NULL,
                 srvinfo->rolname,
                 false, "SERVER", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Handle the ACL */
    dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
            "FOREIGN SERVER",
            qsrvname, NULL, srvinfo->dobj.name,
            NULL, srvinfo->rolname,
            srvinfo->srvacl);

    /* Dump user mappings */
    dumpUserMappings(fout,
                     srvinfo->dobj.name, NULL,
                     srvinfo->rolname,
                     srvinfo->dobj.catId, srvinfo->dobj.dumpId);

    /* Dump Foreign Server Comments */
    dumpComment(fout, labelq->data,
                NULL, srvinfo->rolname,
                srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);

    free(qsrvname);

    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
}

static void dumpFunc ( Archive fout,
FuncInfo finfo 
) [static]

Definition at line 9485 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, appendStringLiteralDQ(), ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), disable_dollar_quoting, _funcInfo::dobj, _dumpableObject::dump, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), ExecuteSqlQueryForSingleRow(), exit_horribly(), fmtId(), format_function_arguments(), format_function_arguments_old(), format_function_signature(), free, getFormattedTypeName(), i, _dumpableObject::name, _funcInfo::nargs, NULL, CatalogId::oid, parsePGArray(), pg_strcasecmp(), PQclear(), PQfnumber(), PQgetvalue(), _funcInfo::proacl, _funcInfo::prorettype, PROVOLATILE_IMMUTABLE, PROVOLATILE_STABLE, PROVOLATILE_VOLATILE, Archive::remoteVersion, _funcInfo::rolname, SECTION_PRE_DATA, selectSourceSchema(), write_msg(), and zeroAsOpaque.

Referenced by dumpDumpableObject().

{
    PQExpBuffer query;
    PQExpBuffer q;
    PQExpBuffer delqry;
    PQExpBuffer labelq;
    PQExpBuffer asPart;
    PGresult   *res;
    char       *funcsig;        /* identity signature */
    char       *funcfullsig;    /* full signature */
    char       *funcsig_tag;
    char       *proretset;
    char       *prosrc;
    char       *probin;
    char       *funcargs;
    char       *funciargs;
    char       *funcresult;
    char       *proallargtypes;
    char       *proargmodes;
    char       *proargnames;
    char       *proiswindow;
    char       *provolatile;
    char       *proisstrict;
    char       *prosecdef;
    char       *proleakproof;
    char       *proconfig;
    char       *procost;
    char       *prorows;
    char       *lanname;
    char       *rettypename;
    int         nallargs;
    char      **allargtypes = NULL;
    char      **argmodes = NULL;
    char      **argnames = NULL;
    char      **configitems = NULL;
    int         nconfigitems = 0;
    int         i;

    /* Skip if not to be dumped */
    if (!finfo->dobj.dump || dataOnly)
        return;

    query = createPQExpBuffer();
    q = createPQExpBuffer();
    delqry = createPQExpBuffer();
    labelq = createPQExpBuffer();
    asPart = createPQExpBuffer();

    /* Set proper schema search path so type references list correctly */
    selectSourceSchema(fout, finfo->dobj.namespace->dobj.name);

    /* Fetch function-specific details */
    if (fout->remoteVersion >= 90200)
    {
        /*
         * proleakproof was added at v9.2
         */
        appendPQExpBuffer(query,
                          "SELECT proretset, prosrc, probin, "
                    "pg_catalog.pg_get_function_arguments(oid) AS funcargs, "
          "pg_catalog.pg_get_function_identity_arguments(oid) AS funciargs, "
                     "pg_catalog.pg_get_function_result(oid) AS funcresult, "
                          "proiswindow, provolatile, proisstrict, prosecdef, "
                          "proleakproof, proconfig, procost, prorows, "
                          "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
                          "FROM pg_catalog.pg_proc "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          finfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 80400)
    {
        /*
         * In 8.4 and up we rely on pg_get_function_arguments and
         * pg_get_function_result instead of examining proallargtypes etc.
         */
        appendPQExpBuffer(query,
                          "SELECT proretset, prosrc, probin, "
                    "pg_catalog.pg_get_function_arguments(oid) AS funcargs, "
          "pg_catalog.pg_get_function_identity_arguments(oid) AS funciargs, "
                     "pg_catalog.pg_get_function_result(oid) AS funcresult, "
                          "proiswindow, provolatile, proisstrict, prosecdef, "
                          "false AS proleakproof, "
                          " proconfig, procost, prorows, "
                          "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
                          "FROM pg_catalog.pg_proc "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          finfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 80300)
    {
        appendPQExpBuffer(query,
                          "SELECT proretset, prosrc, probin, "
                          "proallargtypes, proargmodes, proargnames, "
                          "false AS proiswindow, "
                          "provolatile, proisstrict, prosecdef, "
                          "false AS proleakproof, "
                          "proconfig, procost, prorows, "
                          "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
                          "FROM pg_catalog.pg_proc "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          finfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 80100)
    {
        appendPQExpBuffer(query,
                          "SELECT proretset, prosrc, probin, "
                          "proallargtypes, proargmodes, proargnames, "
                          "false AS proiswindow, "
                          "provolatile, proisstrict, prosecdef, "
                          "false AS proleakproof, "
                          "null AS proconfig, 0 AS procost, 0 AS prorows, "
                          "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
                          "FROM pg_catalog.pg_proc "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          finfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 80000)
    {
        appendPQExpBuffer(query,
                          "SELECT proretset, prosrc, probin, "
                          "null AS proallargtypes, "
                          "null AS proargmodes, "
                          "proargnames, "
                          "false AS proiswindow, "
                          "provolatile, proisstrict, prosecdef, "
                          "false AS proleakproof, "
                          "null AS proconfig, 0 AS procost, 0 AS prorows, "
                          "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
                          "FROM pg_catalog.pg_proc "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          finfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 70300)
    {
        appendPQExpBuffer(query,
                          "SELECT proretset, prosrc, probin, "
                          "null AS proallargtypes, "
                          "null AS proargmodes, "
                          "null AS proargnames, "
                          "false AS proiswindow, "
                          "provolatile, proisstrict, prosecdef, "
                          "false AS proleakproof, "
                          "null AS proconfig, 0 AS procost, 0 AS prorows, "
                          "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
                          "FROM pg_catalog.pg_proc "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          finfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 70100)
    {
        appendPQExpBuffer(query,
                          "SELECT proretset, prosrc, probin, "
                          "null AS proallargtypes, "
                          "null AS proargmodes, "
                          "null AS proargnames, "
                          "false AS proiswindow, "
             "case when proiscachable then 'i' else 'v' end AS provolatile, "
                          "proisstrict, "
                          "false AS prosecdef, "
                          "false AS proleakproof, "
                          "null AS proconfig, 0 AS procost, 0 AS prorows, "
          "(SELECT lanname FROM pg_language WHERE oid = prolang) AS lanname "
                          "FROM pg_proc "
                          "WHERE oid = '%u'::oid",
                          finfo->dobj.catId.oid);
    }
    else
    {
        appendPQExpBuffer(query,
                          "SELECT proretset, prosrc, probin, "
                          "null AS proallargtypes, "
                          "null AS proargmodes, "
                          "null AS proargnames, "
                          "false AS proiswindow, "
             "CASE WHEN proiscachable THEN 'i' ELSE 'v' END AS provolatile, "
                          "false AS proisstrict, "
                          "false AS prosecdef, "
                          "false AS proleakproof, "
                          "NULL AS proconfig, 0 AS procost, 0 AS prorows, "
          "(SELECT lanname FROM pg_language WHERE oid = prolang) AS lanname "
                          "FROM pg_proc "
                          "WHERE oid = '%u'::oid",
                          finfo->dobj.catId.oid);
    }

    res = ExecuteSqlQueryForSingleRow(fout, query->data);

    proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
    prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
    probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
    if (fout->remoteVersion >= 80400)
    {
        funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
        funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
        funcresult = PQgetvalue(res, 0, PQfnumber(res, "funcresult"));
        proallargtypes = proargmodes = proargnames = NULL;
    }
    else
    {
        proallargtypes = PQgetvalue(res, 0, PQfnumber(res, "proallargtypes"));
        proargmodes = PQgetvalue(res, 0, PQfnumber(res, "proargmodes"));
        proargnames = PQgetvalue(res, 0, PQfnumber(res, "proargnames"));
        funcargs = funciargs = funcresult = NULL;
    }
    proiswindow = PQgetvalue(res, 0, PQfnumber(res, "proiswindow"));
    provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
    proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
    prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
    proleakproof = PQgetvalue(res, 0, PQfnumber(res, "proleakproof"));
    proconfig = PQgetvalue(res, 0, PQfnumber(res, "proconfig"));
    procost = PQgetvalue(res, 0, PQfnumber(res, "procost"));
    prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
    lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));

    /*
     * See backend/commands/functioncmds.c for details of how the 'AS' clause
     * is used.  In 8.4 and up, an unused probin is NULL (here ""); previous
     * versions would set it to "-".  There are no known cases in which prosrc
     * is unused, so the tests below for "-" are probably useless.
     */
    if (probin[0] != '\0' && strcmp(probin, "-") != 0)
    {
        appendPQExpBuffer(asPart, "AS ");
        appendStringLiteralAH(asPart, probin, fout);
        if (strcmp(prosrc, "-") != 0)
        {
            appendPQExpBuffer(asPart, ", ");

            /*
             * where we have bin, use dollar quoting if allowed and src
             * contains quote or backslash; else use regular quoting.
             */
            if (disable_dollar_quoting ||
              (strchr(prosrc, '\'') == NULL && strchr(prosrc, '\\') == NULL))
                appendStringLiteralAH(asPart, prosrc, fout);
            else
                appendStringLiteralDQ(asPart, prosrc, NULL);
        }
    }
    else
    {
        if (strcmp(prosrc, "-") != 0)
        {
            appendPQExpBuffer(asPart, "AS ");
            /* with no bin, dollar quote src unconditionally if allowed */
            if (disable_dollar_quoting)
                appendStringLiteralAH(asPart, prosrc, fout);
            else
                appendStringLiteralDQ(asPart, prosrc, NULL);
        }
    }

    nallargs = finfo->nargs;    /* unless we learn different from allargs */

    if (proallargtypes && *proallargtypes)
    {
        int         nitems = 0;

        if (!parsePGArray(proallargtypes, &allargtypes, &nitems) ||
            nitems < finfo->nargs)
        {
            write_msg(NULL, "WARNING: could not parse proallargtypes array\n");
            if (allargtypes)
                free(allargtypes);
            allargtypes = NULL;
        }
        else
            nallargs = nitems;
    }

    if (proargmodes && *proargmodes)
    {
        int         nitems = 0;

        if (!parsePGArray(proargmodes, &argmodes, &nitems) ||
            nitems != nallargs)
        {
            write_msg(NULL, "WARNING: could not parse proargmodes array\n");
            if (argmodes)
                free(argmodes);
            argmodes = NULL;
        }
    }

    if (proargnames && *proargnames)
    {
        int         nitems = 0;

        if (!parsePGArray(proargnames, &argnames, &nitems) ||
            nitems != nallargs)
        {
            write_msg(NULL, "WARNING: could not parse proargnames array\n");
            if (argnames)
                free(argnames);
            argnames = NULL;
        }
    }

    if (proconfig && *proconfig)
    {
        if (!parsePGArray(proconfig, &configitems, &nconfigitems))
        {
            write_msg(NULL, "WARNING: could not parse proconfig array\n");
            if (configitems)
                free(configitems);
            configitems = NULL;
            nconfigitems = 0;
        }
    }

    if (funcargs)
    {
        /* 8.4 or later; we rely on server-side code for most of the work */
        funcfullsig = format_function_arguments(finfo, funcargs);
        funcsig = format_function_arguments(finfo, funciargs);
    }
    else
    {
        /* pre-8.4, do it ourselves */
        funcsig = format_function_arguments_old(fout,
                                                finfo, nallargs, allargtypes,
                                                argmodes, argnames);
        funcfullsig = funcsig;
    }

    funcsig_tag = format_function_signature(fout, finfo, false);

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delqry, "DROP FUNCTION %s.%s;\n",
                      fmtId(finfo->dobj.namespace->dobj.name),
                      funcsig);

    appendPQExpBuffer(q, "CREATE FUNCTION %s ", funcfullsig);
    if (funcresult)
        appendPQExpBuffer(q, "RETURNS %s", funcresult);
    else
    {
        rettypename = getFormattedTypeName(fout, finfo->prorettype,
                                           zeroAsOpaque);
        appendPQExpBuffer(q, "RETURNS %s%s",
                          (proretset[0] == 't') ? "SETOF " : "",
                          rettypename);
        free(rettypename);
    }

    appendPQExpBuffer(q, "\n    LANGUAGE %s", fmtId(lanname));

    if (proiswindow[0] == 't')
        appendPQExpBuffer(q, " WINDOW");

    if (provolatile[0] != PROVOLATILE_VOLATILE)
    {
        if (provolatile[0] == PROVOLATILE_IMMUTABLE)
            appendPQExpBuffer(q, " IMMUTABLE");
        else if (provolatile[0] == PROVOLATILE_STABLE)
            appendPQExpBuffer(q, " STABLE");
        else if (provolatile[0] != PROVOLATILE_VOLATILE)
            exit_horribly(NULL, "unrecognized provolatile value for function \"%s\"\n",
                          finfo->dobj.name);
    }

    if (proisstrict[0] == 't')
        appendPQExpBuffer(q, " STRICT");

    if (prosecdef[0] == 't')
        appendPQExpBuffer(q, " SECURITY DEFINER");

    if (proleakproof[0] == 't')
        appendPQExpBuffer(q, " LEAKPROOF");

    /*
     * COST and ROWS are emitted only if present and not default, so as not to
     * break backwards-compatibility of the dump without need.  Keep this code
     * in sync with the defaults in functioncmds.c.
     */
    if (strcmp(procost, "0") != 0)
    {
        if (strcmp(lanname, "internal") == 0 || strcmp(lanname, "c") == 0)
        {
            /* default cost is 1 */
            if (strcmp(procost, "1") != 0)
                appendPQExpBuffer(q, " COST %s", procost);
        }
        else
        {
            /* default cost is 100 */
            if (strcmp(procost, "100") != 0)
                appendPQExpBuffer(q, " COST %s", procost);
        }
    }
    if (proretset[0] == 't' &&
        strcmp(prorows, "0") != 0 && strcmp(prorows, "1000") != 0)
        appendPQExpBuffer(q, " ROWS %s", prorows);

    for (i = 0; i < nconfigitems; i++)
    {
        /* we feel free to scribble on configitems[] here */
        char       *configitem = configitems[i];
        char       *pos;

        pos = strchr(configitem, '=');
        if (pos == NULL)
            continue;
        *pos++ = '\0';
        appendPQExpBuffer(q, "\n    SET %s TO ", fmtId(configitem));

        /*
         * Some GUC variable names are 'LIST' type and hence must not be
         * quoted.
         */
        if (pg_strcasecmp(configitem, "DateStyle") == 0
            || pg_strcasecmp(configitem, "search_path") == 0)
            appendPQExpBuffer(q, "%s", pos);
        else
            appendStringLiteralAH(q, pos, fout);
    }

    appendPQExpBuffer(q, "\n    %s;\n", asPart->data);

    appendPQExpBuffer(labelq, "FUNCTION %s", funcsig);

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &finfo->dobj, labelq->data);

    ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
                 funcsig_tag,
                 finfo->dobj.namespace->dobj.name,
                 NULL,
                 finfo->rolname, false,
                 "FUNCTION", SECTION_PRE_DATA,
                 q->data, delqry->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Function Comments and Security Labels */
    dumpComment(fout, labelq->data,
                finfo->dobj.namespace->dobj.name, finfo->rolname,
                finfo->dobj.catId, 0, finfo->dobj.dumpId);
    dumpSecLabel(fout, labelq->data,
                 finfo->dobj.namespace->dobj.name, finfo->rolname,
                 finfo->dobj.catId, 0, finfo->dobj.dumpId);

    dumpACL(fout, finfo->dobj.catId, finfo->dobj.dumpId, "FUNCTION",
            funcsig, NULL, funcsig_tag,
            finfo->dobj.namespace->dobj.name,
            finfo->rolname, finfo->proacl);

    PQclear(res);

    destroyPQExpBuffer(query);
    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delqry);
    destroyPQExpBuffer(labelq);
    destroyPQExpBuffer(asPart);
    free(funcsig);
    free(funcsig_tag);
    if (allargtypes)
        free(allargtypes);
    if (argmodes)
        free(argmodes);
    if (argnames)
        free(argnames);
    if (configitems)
        free(configitems);
}

static void dumpIndex ( Archive fout,
IndxInfo indxinfo 
) [static]

Definition at line 13466 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), binary_upgrade, binary_upgrade_set_pg_class_oids(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _indxInfo::dobj, dumpComment(), _dumpableObject::dumpId, fmtId(), _indxInfo::indexconstraint, _indxInfo::indexdef, _indxInfo::indextable, _indxInfo::indisclustered, _dumpableObject::name, NULL, CatalogId::oid, _tableInfo::rolname, SECTION_POST_DATA, and _indxInfo::tablespace.

Referenced by dumpDumpableObject().

{
    TableInfo  *tbinfo = indxinfo->indextable;
    PQExpBuffer q;
    PQExpBuffer delq;
    PQExpBuffer labelq;

    if (dataOnly)
        return;

    q = createPQExpBuffer();
    delq = createPQExpBuffer();
    labelq = createPQExpBuffer();

    appendPQExpBuffer(labelq, "INDEX %s",
                      fmtId(indxinfo->dobj.name));

    /*
     * If there's an associated constraint, don't dump the index per se, but
     * do dump any comment for it.  (This is safe because dependency ordering
     * will have ensured the constraint is emitted first.)
     */
    if (indxinfo->indexconstraint == 0)
    {
        if (binary_upgrade)
            binary_upgrade_set_pg_class_oids(fout, q,
                                             indxinfo->dobj.catId.oid, true);

        /* Plain secondary index */
        appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef);

        /* If the index is clustered, we need to record that. */
        if (indxinfo->indisclustered)
        {
            appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
                              fmtId(tbinfo->dobj.name));
            appendPQExpBuffer(q, " ON %s;\n",
                              fmtId(indxinfo->dobj.name));
        }

        /*
         * DROP must be fully qualified in case same name appears in
         * pg_catalog
         */
        appendPQExpBuffer(delq, "DROP INDEX %s.",
                          fmtId(tbinfo->dobj.namespace->dobj.name));
        appendPQExpBuffer(delq, "%s;\n",
                          fmtId(indxinfo->dobj.name));

        ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
                     indxinfo->dobj.name,
                     tbinfo->dobj.namespace->dobj.name,
                     indxinfo->tablespace,
                     tbinfo->rolname, false,
                     "INDEX", SECTION_POST_DATA,
                     q->data, delq->data, NULL,
                     NULL, 0,
                     NULL, NULL);
    }

    /* Dump Index Comments */
    dumpComment(fout, labelq->data,
                tbinfo->dobj.namespace->dobj.name,
                tbinfo->rolname,
                indxinfo->dobj.catId, 0, indxinfo->dobj.dumpId);

    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
}

static void dumpNamespace ( Archive fout,
NamespaceInfo nspinfo 
) [static]

Definition at line 7764 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _namespaceInfo::dobj, _dumpableObject::dump, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), fmtId(), free, _dumpableObject::name, _namespaceInfo::nspacl, NULL, pg_strdup(), _namespaceInfo::rolname, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

{
    PQExpBuffer q;
    PQExpBuffer delq;
    PQExpBuffer labelq;
    char       *qnspname;

    /* Skip if not to be dumped */
    if (!nspinfo->dobj.dump || dataOnly)
        return;

    /* don't dump dummy namespace from pre-7.3 source */
    if (strlen(nspinfo->dobj.name) == 0)
        return;

    q = createPQExpBuffer();
    delq = createPQExpBuffer();
    labelq = createPQExpBuffer();

    qnspname = pg_strdup(fmtId(nspinfo->dobj.name));

    appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);

    appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);

    appendPQExpBuffer(labelq, "SCHEMA %s", qnspname);

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &nspinfo->dobj, labelq->data);

    ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
                 nspinfo->dobj.name,
                 NULL, NULL,
                 nspinfo->rolname,
                 false, "SCHEMA", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Schema Comments and Security Labels */
    dumpComment(fout, labelq->data,
                NULL, nspinfo->rolname,
                nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
    dumpSecLabel(fout, labelq->data,
                 NULL, nspinfo->rolname,
                 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);

    dumpACL(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId, "SCHEMA",
            qnspname, NULL, nspinfo->dobj.name, NULL,
            nspinfo->rolname, nspinfo->nspacl);

    free(qnspname);

    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
}

static void dumpOpclass ( Archive fout,
OpclassInfo opcinfo 
) [static]

Definition at line 10475 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _opclassInfo::dobj, _dumpableObject::dump, dumpComment(), _dumpableObject::dumpId, ExecuteSqlQuery(), ExecuteSqlQueryForSingleRow(), fmtId(), free, i, _dumpableObject::name, NULL, CatalogId::oid, pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, resetPQExpBuffer(), _opclassInfo::rolname, SECTION_PRE_DATA, and selectSourceSchema().

Referenced by dumpDumpableObject().

{
    PQExpBuffer query;
    PQExpBuffer q;
    PQExpBuffer delq;
    PQExpBuffer labelq;
    PGresult   *res;
    int         ntups;
    int         i_opcintype;
    int         i_opckeytype;
    int         i_opcdefault;
    int         i_opcfamily;
    int         i_opcfamilyname;
    int         i_opcfamilynsp;
    int         i_amname;
    int         i_amopstrategy;
    int         i_amopreqcheck;
    int         i_amopopr;
    int         i_sortfamily;
    int         i_sortfamilynsp;
    int         i_amprocnum;
    int         i_amproc;
    int         i_amproclefttype;
    int         i_amprocrighttype;
    char       *opcintype;
    char       *opckeytype;
    char       *opcdefault;
    char       *opcfamily;
    char       *opcfamilyname;
    char       *opcfamilynsp;
    char       *amname;
    char       *amopstrategy;
    char       *amopreqcheck;
    char       *amopopr;
    char       *sortfamily;
    char       *sortfamilynsp;
    char       *amprocnum;
    char       *amproc;
    char       *amproclefttype;
    char       *amprocrighttype;
    bool        needComma;
    int         i;

    /* Skip if not to be dumped */
    if (!opcinfo->dobj.dump || dataOnly)
        return;

    /*
     * XXX currently we do not implement dumping of operator classes from
     * pre-7.3 databases.  This could be done but it seems not worth the
     * trouble.
     */
    if (fout->remoteVersion < 70300)
        return;

    query = createPQExpBuffer();
    q = createPQExpBuffer();
    delq = createPQExpBuffer();
    labelq = createPQExpBuffer();

    /* Make sure we are in proper schema so regoperator works correctly */
    selectSourceSchema(fout, opcinfo->dobj.namespace->dobj.name);

    /* Get additional fields from the pg_opclass row */
    if (fout->remoteVersion >= 80300)
    {
        appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
                          "opckeytype::pg_catalog.regtype, "
                          "opcdefault, opcfamily, "
                          "opfname AS opcfamilyname, "
                          "nspname AS opcfamilynsp, "
                          "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
                          "FROM pg_catalog.pg_opclass c "
                   "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
               "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
                          "WHERE c.oid = '%u'::pg_catalog.oid",
                          opcinfo->dobj.catId.oid);
    }
    else
    {
        appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
                          "opckeytype::pg_catalog.regtype, "
                          "opcdefault, NULL AS opcfamily, "
                          "NULL AS opcfamilyname, "
                          "NULL AS opcfamilynsp, "
        "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcamid) AS amname "
                          "FROM pg_catalog.pg_opclass "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          opcinfo->dobj.catId.oid);
    }

    res = ExecuteSqlQueryForSingleRow(fout, query->data);

    i_opcintype = PQfnumber(res, "opcintype");
    i_opckeytype = PQfnumber(res, "opckeytype");
    i_opcdefault = PQfnumber(res, "opcdefault");
    i_opcfamily = PQfnumber(res, "opcfamily");
    i_opcfamilyname = PQfnumber(res, "opcfamilyname");
    i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
    i_amname = PQfnumber(res, "amname");

    opcintype = PQgetvalue(res, 0, i_opcintype);
    opckeytype = PQgetvalue(res, 0, i_opckeytype);
    opcdefault = PQgetvalue(res, 0, i_opcdefault);
    /* opcfamily will still be needed after we PQclear res */
    opcfamily = pg_strdup(PQgetvalue(res, 0, i_opcfamily));
    opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
    opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp);
    /* amname will still be needed after we PQclear res */
    amname = pg_strdup(PQgetvalue(res, 0, i_amname));

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
                      fmtId(opcinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delq, ".%s",
                      fmtId(opcinfo->dobj.name));
    appendPQExpBuffer(delq, " USING %s;\n",
                      fmtId(amname));

    /* Build the fixed portion of the CREATE command */
    appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n    ",
                      fmtId(opcinfo->dobj.name));
    if (strcmp(opcdefault, "t") == 0)
        appendPQExpBuffer(q, "DEFAULT ");
    appendPQExpBuffer(q, "FOR TYPE %s USING %s",
                      opcintype,
                      fmtId(amname));
    if (strlen(opcfamilyname) > 0 &&
        (strcmp(opcfamilyname, opcinfo->dobj.name) != 0 ||
         strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0))
    {
        appendPQExpBuffer(q, " FAMILY ");
        if (strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)
            appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
        appendPQExpBuffer(q, "%s", fmtId(opcfamilyname));
    }
    appendPQExpBuffer(q, " AS\n    ");

    needComma = false;

    if (strcmp(opckeytype, "-") != 0)
    {
        appendPQExpBuffer(q, "STORAGE %s",
                          opckeytype);
        needComma = true;
    }

    PQclear(res);

    /*
     * Now fetch and print the OPERATOR entries (pg_amop rows).
     *
     * Print only those opfamily members that are tied to the opclass by
     * pg_depend entries.
     *
     * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping an
     * older server's opclass in which it is used.  This is to avoid
     * hard-to-detect breakage if a newer pg_dump is used to dump from an
     * older server and then reload into that old version.  This can go away
     * once 8.3 is so old as to not be of interest to anyone.
     */
    resetPQExpBuffer(query);

    if (fout->remoteVersion >= 90100)
    {
        appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
                          "amopopr::pg_catalog.regoperator, "
                          "opfname AS sortfamily, "
                          "nspname AS sortfamilynsp "
                   "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
                          "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
              "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
               "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
           "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                          "AND refobjid = '%u'::pg_catalog.oid "
                          "AND amopfamily = '%s'::pg_catalog.oid "
                          "ORDER BY amopstrategy",
                          opcinfo->dobj.catId.oid,
                          opcfamily);
    }
    else if (fout->remoteVersion >= 80400)
    {
        appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
                          "amopopr::pg_catalog.regoperator, "
                          "NULL AS sortfamily, "
                          "NULL AS sortfamilynsp "
                          "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
           "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                          "AND refobjid = '%u'::pg_catalog.oid "
                   "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
                          "AND objid = ao.oid "
                          "ORDER BY amopstrategy",
                          opcinfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 80300)
    {
        appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
                          "amopopr::pg_catalog.regoperator, "
                          "NULL AS sortfamily, "
                          "NULL AS sortfamilynsp "
                          "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
           "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                          "AND refobjid = '%u'::pg_catalog.oid "
                   "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
                          "AND objid = ao.oid "
                          "ORDER BY amopstrategy",
                          opcinfo->dobj.catId.oid);
    }
    else
    {
        /*
         * Here, we print all entries since there are no opfamilies and hence
         * no loose operators to worry about.
         */
        appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
                          "amopopr::pg_catalog.regoperator, "
                          "NULL AS sortfamily, "
                          "NULL AS sortfamilynsp "
                          "FROM pg_catalog.pg_amop "
                          "WHERE amopclaid = '%u'::pg_catalog.oid "
                          "ORDER BY amopstrategy",
                          opcinfo->dobj.catId.oid);
    }

    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    ntups = PQntuples(res);

    i_amopstrategy = PQfnumber(res, "amopstrategy");
    i_amopreqcheck = PQfnumber(res, "amopreqcheck");
    i_amopopr = PQfnumber(res, "amopopr");
    i_sortfamily = PQfnumber(res, "sortfamily");
    i_sortfamilynsp = PQfnumber(res, "sortfamilynsp");

    for (i = 0; i < ntups; i++)
    {
        amopstrategy = PQgetvalue(res, i, i_amopstrategy);
        amopreqcheck = PQgetvalue(res, i, i_amopreqcheck);
        amopopr = PQgetvalue(res, i, i_amopopr);
        sortfamily = PQgetvalue(res, i, i_sortfamily);
        sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp);

        if (needComma)
            appendPQExpBuffer(q, " ,\n    ");

        appendPQExpBuffer(q, "OPERATOR %s %s",
                          amopstrategy, amopopr);

        if (strlen(sortfamily) > 0)
        {
            appendPQExpBuffer(q, " FOR ORDER BY ");
            if (strcmp(sortfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)
                appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
            appendPQExpBuffer(q, "%s", fmtId(sortfamily));
        }

        if (strcmp(amopreqcheck, "t") == 0)
            appendPQExpBuffer(q, " RECHECK");

        needComma = true;
    }

    PQclear(res);

    /*
     * Now fetch and print the FUNCTION entries (pg_amproc rows).
     *
     * Print only those opfamily members that are tied to the opclass by
     * pg_depend entries.
     *
     * We print the amproclefttype/amprocrighttype even though in most cases
     * the backend could deduce the right values, because of the corner case
     * of a btree sort support function for a cross-type comparison.  That's
     * only allowed in 9.2 and later, but for simplicity print them in all
     * versions that have the columns.
     */
    resetPQExpBuffer(query);

    if (fout->remoteVersion >= 80300)
    {
        appendPQExpBuffer(query, "SELECT amprocnum, "
                          "amproc::pg_catalog.regprocedure, "
                          "amproclefttype::pg_catalog.regtype, "
                          "amprocrighttype::pg_catalog.regtype "
                        "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
           "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                          "AND refobjid = '%u'::pg_catalog.oid "
                 "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
                          "AND objid = ap.oid "
                          "ORDER BY amprocnum",
                          opcinfo->dobj.catId.oid);
    }
    else
    {
        appendPQExpBuffer(query, "SELECT amprocnum, "
                          "amproc::pg_catalog.regprocedure, "
                          "'' AS amproclefttype, "
                          "'' AS amprocrighttype "
                          "FROM pg_catalog.pg_amproc "
                          "WHERE amopclaid = '%u'::pg_catalog.oid "
                          "ORDER BY amprocnum",
                          opcinfo->dobj.catId.oid);
    }

    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    ntups = PQntuples(res);

    i_amprocnum = PQfnumber(res, "amprocnum");
    i_amproc = PQfnumber(res, "amproc");
    i_amproclefttype = PQfnumber(res, "amproclefttype");
    i_amprocrighttype = PQfnumber(res, "amprocrighttype");

    for (i = 0; i < ntups; i++)
    {
        amprocnum = PQgetvalue(res, i, i_amprocnum);
        amproc = PQgetvalue(res, i, i_amproc);
        amproclefttype = PQgetvalue(res, i, i_amproclefttype);
        amprocrighttype = PQgetvalue(res, i, i_amprocrighttype);

        if (needComma)
            appendPQExpBuffer(q, " ,\n    ");

        appendPQExpBuffer(q, "FUNCTION %s", amprocnum);

        if (*amproclefttype && *amprocrighttype)
            appendPQExpBuffer(q, " (%s, %s)", amproclefttype, amprocrighttype);

        appendPQExpBuffer(q, " %s", amproc);

        needComma = true;
    }

    PQclear(res);

    appendPQExpBuffer(q, ";\n");

    appendPQExpBuffer(labelq, "OPERATOR CLASS %s",
                      fmtId(opcinfo->dobj.name));
    appendPQExpBuffer(labelq, " USING %s",
                      fmtId(amname));

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &opcinfo->dobj, labelq->data);

    ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
                 opcinfo->dobj.name,
                 opcinfo->dobj.namespace->dobj.name,
                 NULL,
                 opcinfo->rolname,
                 false, "OPERATOR CLASS", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Operator Class Comments */
    dumpComment(fout, labelq->data,
                NULL, opcinfo->rolname,
                opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);

    free(amname);
    destroyPQExpBuffer(query);
    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
}

static void dumpOpfamily ( Archive fout,
OpfamilyInfo opfinfo 
) [static]

Definition at line 10852 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _opfamilyInfo::dobj, _dumpableObject::dump, dumpComment(), _dumpableObject::dumpId, ExecuteSqlQuery(), ExecuteSqlQueryForSingleRow(), fmtId(), free, i, _dumpableObject::name, NULL, CatalogId::oid, pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQfnumber(), PQgetvalue(), PQntuples(), Archive::remoteVersion, resetPQExpBuffer(), _opfamilyInfo::rolname, SECTION_PRE_DATA, and selectSourceSchema().

Referenced by dumpDumpableObject().

{
    PQExpBuffer query;
    PQExpBuffer q;
    PQExpBuffer delq;
    PQExpBuffer labelq;
    PGresult   *res;
    PGresult   *res_ops;
    PGresult   *res_procs;
    int         ntups;
    int         i_amname;
    int         i_amopstrategy;
    int         i_amopreqcheck;
    int         i_amopopr;
    int         i_sortfamily;
    int         i_sortfamilynsp;
    int         i_amprocnum;
    int         i_amproc;
    int         i_amproclefttype;
    int         i_amprocrighttype;
    char       *amname;
    char       *amopstrategy;
    char       *amopreqcheck;
    char       *amopopr;
    char       *sortfamily;
    char       *sortfamilynsp;
    char       *amprocnum;
    char       *amproc;
    char       *amproclefttype;
    char       *amprocrighttype;
    bool        needComma;
    int         i;

    /* Skip if not to be dumped */
    if (!opfinfo->dobj.dump || dataOnly)
        return;

    /*
     * We want to dump the opfamily only if (1) it contains "loose" operators
     * or functions, or (2) it contains an opclass with a different name or
     * owner.  Otherwise it's sufficient to let it be created during creation
     * of the contained opclass, and not dumping it improves portability of
     * the dump.  Since we have to fetch the loose operators/funcs anyway, do
     * that first.
     */

    query = createPQExpBuffer();
    q = createPQExpBuffer();
    delq = createPQExpBuffer();
    labelq = createPQExpBuffer();

    /* Make sure we are in proper schema so regoperator works correctly */
    selectSourceSchema(fout, opfinfo->dobj.namespace->dobj.name);

    /*
     * Fetch only those opfamily members that are tied directly to the
     * opfamily by pg_depend entries.
     *
     * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping an
     * older server's opclass in which it is used.  This is to avoid
     * hard-to-detect breakage if a newer pg_dump is used to dump from an
     * older server and then reload into that old version.  This can go away
     * once 8.3 is so old as to not be of interest to anyone.
     */
    if (fout->remoteVersion >= 90100)
    {
        appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
                          "amopopr::pg_catalog.regoperator, "
                          "opfname AS sortfamily, "
                          "nspname AS sortfamilynsp "
                   "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
                          "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
              "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
               "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
          "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                          "AND refobjid = '%u'::pg_catalog.oid "
                          "AND amopfamily = '%u'::pg_catalog.oid "
                          "ORDER BY amopstrategy",
                          opfinfo->dobj.catId.oid,
                          opfinfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 80400)
    {
        appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
                          "amopopr::pg_catalog.regoperator, "
                          "NULL AS sortfamily, "
                          "NULL AS sortfamilynsp "
                          "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
          "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                          "AND refobjid = '%u'::pg_catalog.oid "
                   "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
                          "AND objid = ao.oid "
                          "ORDER BY amopstrategy",
                          opfinfo->dobj.catId.oid);
    }
    else
    {
        appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
                          "amopopr::pg_catalog.regoperator, "
                          "NULL AS sortfamily, "
                          "NULL AS sortfamilynsp "
                          "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
          "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                          "AND refobjid = '%u'::pg_catalog.oid "
                   "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
                          "AND objid = ao.oid "
                          "ORDER BY amopstrategy",
                          opfinfo->dobj.catId.oid);
    }

    res_ops = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    resetPQExpBuffer(query);

    appendPQExpBuffer(query, "SELECT amprocnum, "
                      "amproc::pg_catalog.regprocedure, "
                      "amproclefttype::pg_catalog.regtype, "
                      "amprocrighttype::pg_catalog.regtype "
                      "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
          "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                      "AND refobjid = '%u'::pg_catalog.oid "
                 "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
                      "AND objid = ap.oid "
                      "ORDER BY amprocnum",
                      opfinfo->dobj.catId.oid);

    res_procs = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    if (PQntuples(res_ops) == 0 && PQntuples(res_procs) == 0)
    {
        /* No loose members, so check contained opclasses */
        resetPQExpBuffer(query);

        appendPQExpBuffer(query, "SELECT 1 "
                          "FROM pg_catalog.pg_opclass c, pg_catalog.pg_opfamily f, pg_catalog.pg_depend "
                          "WHERE f.oid = '%u'::pg_catalog.oid "
            "AND refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                          "AND refobjid = f.oid "
                "AND classid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                          "AND objid = c.oid "
                          "AND (opcname != opfname OR opcnamespace != opfnamespace OR opcowner != opfowner) "
                          "LIMIT 1",
                          opfinfo->dobj.catId.oid);

        res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

        if (PQntuples(res) == 0)
        {
            /* no need to dump it, so bail out */
            PQclear(res);
            PQclear(res_ops);
            PQclear(res_procs);
            destroyPQExpBuffer(query);
            destroyPQExpBuffer(q);
            destroyPQExpBuffer(delq);
            destroyPQExpBuffer(labelq);
            return;
        }

        PQclear(res);
    }

    /* Get additional fields from the pg_opfamily row */
    resetPQExpBuffer(query);

    appendPQExpBuffer(query, "SELECT "
     "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opfmethod) AS amname "
                      "FROM pg_catalog.pg_opfamily "
                      "WHERE oid = '%u'::pg_catalog.oid",
                      opfinfo->dobj.catId.oid);

    res = ExecuteSqlQueryForSingleRow(fout, query->data);

    i_amname = PQfnumber(res, "amname");

    /* amname will still be needed after we PQclear res */
    amname = pg_strdup(PQgetvalue(res, 0, i_amname));

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s",
                      fmtId(opfinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delq, ".%s",
                      fmtId(opfinfo->dobj.name));
    appendPQExpBuffer(delq, " USING %s;\n",
                      fmtId(amname));

    /* Build the fixed portion of the CREATE command */
    appendPQExpBuffer(q, "CREATE OPERATOR FAMILY %s",
                      fmtId(opfinfo->dobj.name));
    appendPQExpBuffer(q, " USING %s;\n",
                      fmtId(amname));

    PQclear(res);

    /* Do we need an ALTER to add loose members? */
    if (PQntuples(res_ops) > 0 || PQntuples(res_procs) > 0)
    {
        appendPQExpBuffer(q, "ALTER OPERATOR FAMILY %s",
                          fmtId(opfinfo->dobj.name));
        appendPQExpBuffer(q, " USING %s ADD\n    ",
                          fmtId(amname));

        needComma = false;

        /*
         * Now fetch and print the OPERATOR entries (pg_amop rows).
         */
        ntups = PQntuples(res_ops);

        i_amopstrategy = PQfnumber(res_ops, "amopstrategy");
        i_amopreqcheck = PQfnumber(res_ops, "amopreqcheck");
        i_amopopr = PQfnumber(res_ops, "amopopr");
        i_sortfamily = PQfnumber(res_ops, "sortfamily");
        i_sortfamilynsp = PQfnumber(res_ops, "sortfamilynsp");

        for (i = 0; i < ntups; i++)
        {
            amopstrategy = PQgetvalue(res_ops, i, i_amopstrategy);
            amopreqcheck = PQgetvalue(res_ops, i, i_amopreqcheck);
            amopopr = PQgetvalue(res_ops, i, i_amopopr);
            sortfamily = PQgetvalue(res_ops, i, i_sortfamily);
            sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp);

            if (needComma)
                appendPQExpBuffer(q, " ,\n    ");

            appendPQExpBuffer(q, "OPERATOR %s %s",
                              amopstrategy, amopopr);

            if (strlen(sortfamily) > 0)
            {
                appendPQExpBuffer(q, " FOR ORDER BY ");
                if (strcmp(sortfamilynsp, opfinfo->dobj.namespace->dobj.name) != 0)
                    appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
                appendPQExpBuffer(q, "%s", fmtId(sortfamily));
            }

            if (strcmp(amopreqcheck, "t") == 0)
                appendPQExpBuffer(q, " RECHECK");

            needComma = true;
        }

        /*
         * Now fetch and print the FUNCTION entries (pg_amproc rows).
         */
        ntups = PQntuples(res_procs);

        i_amprocnum = PQfnumber(res_procs, "amprocnum");
        i_amproc = PQfnumber(res_procs, "amproc");
        i_amproclefttype = PQfnumber(res_procs, "amproclefttype");
        i_amprocrighttype = PQfnumber(res_procs, "amprocrighttype");

        for (i = 0; i < ntups; i++)
        {
            amprocnum = PQgetvalue(res_procs, i, i_amprocnum);
            amproc = PQgetvalue(res_procs, i, i_amproc);
            amproclefttype = PQgetvalue(res_procs, i, i_amproclefttype);
            amprocrighttype = PQgetvalue(res_procs, i, i_amprocrighttype);

            if (needComma)
                appendPQExpBuffer(q, " ,\n    ");

            appendPQExpBuffer(q, "FUNCTION %s (%s, %s) %s",
                              amprocnum, amproclefttype, amprocrighttype,
                              amproc);

            needComma = true;
        }

        appendPQExpBuffer(q, ";\n");
    }

    appendPQExpBuffer(labelq, "OPERATOR FAMILY %s",
                      fmtId(opfinfo->dobj.name));
    appendPQExpBuffer(labelq, " USING %s",
                      fmtId(amname));

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &opfinfo->dobj, labelq->data);

    ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId,
                 opfinfo->dobj.name,
                 opfinfo->dobj.namespace->dobj.name,
                 NULL,
                 opfinfo->rolname,
                 false, "OPERATOR FAMILY", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Operator Family Comments */
    dumpComment(fout, labelq->data,
                NULL, opfinfo->rolname,
                opfinfo->dobj.catId, 0, opfinfo->dobj.dumpId);

    free(amname);
    PQclear(res_ops);
    PQclear(res_procs);
    destroyPQExpBuffer(query);
    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
}

static void dumpOpr ( Archive fout,
OprInfo oprinfo 
) [static]

Definition at line 10106 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, convertOperatorReference(), convertRegProcReference(), createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _oprInfo::dobj, _dumpableObject::dump, dumpComment(), _dumpableObject::dumpId, ExecuteSqlQueryForSingleRow(), fmtId(), _dumpableObject::name, name, NULL, CatalogId::oid, OidIsValid, _oprInfo::oprcode, PQclear(), PQfnumber(), PQgetvalue(), Archive::remoteVersion, _oprInfo::rolname, SECTION_PRE_DATA, and selectSourceSchema().

Referenced by dumpDumpableObject().

{
    PQExpBuffer query;
    PQExpBuffer q;
    PQExpBuffer delq;
    PQExpBuffer labelq;
    PQExpBuffer oprid;
    PQExpBuffer details;
    const char *name;
    PGresult   *res;
    int         i_oprkind;
    int         i_oprcode;
    int         i_oprleft;
    int         i_oprright;
    int         i_oprcom;
    int         i_oprnegate;
    int         i_oprrest;
    int         i_oprjoin;
    int         i_oprcanmerge;
    int         i_oprcanhash;
    char       *oprkind;
    char       *oprcode;
    char       *oprleft;
    char       *oprright;
    char       *oprcom;
    char       *oprnegate;
    char       *oprrest;
    char       *oprjoin;
    char       *oprcanmerge;
    char       *oprcanhash;

    /* Skip if not to be dumped */
    if (!oprinfo->dobj.dump || dataOnly)
        return;

    /*
     * some operators are invalid because they were the result of user
     * defining operators before commutators exist
     */
    if (!OidIsValid(oprinfo->oprcode))
        return;

    query = createPQExpBuffer();
    q = createPQExpBuffer();
    delq = createPQExpBuffer();
    labelq = createPQExpBuffer();
    oprid = createPQExpBuffer();
    details = createPQExpBuffer();

    /* Make sure we are in proper schema so regoperator works correctly */
    selectSourceSchema(fout, oprinfo->dobj.namespace->dobj.name);

    if (fout->remoteVersion >= 80300)
    {
        appendPQExpBuffer(query, "SELECT oprkind, "
                          "oprcode::pg_catalog.regprocedure, "
                          "oprleft::pg_catalog.regtype, "
                          "oprright::pg_catalog.regtype, "
                          "oprcom::pg_catalog.regoperator, "
                          "oprnegate::pg_catalog.regoperator, "
                          "oprrest::pg_catalog.regprocedure, "
                          "oprjoin::pg_catalog.regprocedure, "
                          "oprcanmerge, oprcanhash "
                          "FROM pg_catalog.pg_operator "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          oprinfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 70300)
    {
        appendPQExpBuffer(query, "SELECT oprkind, "
                          "oprcode::pg_catalog.regprocedure, "
                          "oprleft::pg_catalog.regtype, "
                          "oprright::pg_catalog.regtype, "
                          "oprcom::pg_catalog.regoperator, "
                          "oprnegate::pg_catalog.regoperator, "
                          "oprrest::pg_catalog.regprocedure, "
                          "oprjoin::pg_catalog.regprocedure, "
                          "(oprlsortop != 0) AS oprcanmerge, "
                          "oprcanhash "
                          "FROM pg_catalog.pg_operator "
                          "WHERE oid = '%u'::pg_catalog.oid",
                          oprinfo->dobj.catId.oid);
    }
    else if (fout->remoteVersion >= 70100)
    {
        appendPQExpBuffer(query, "SELECT oprkind, oprcode, "
                          "CASE WHEN oprleft = 0 THEN '-' "
                          "ELSE format_type(oprleft, NULL) END AS oprleft, "
                          "CASE WHEN oprright = 0 THEN '-' "
                          "ELSE format_type(oprright, NULL) END AS oprright, "
                          "oprcom, oprnegate, oprrest, oprjoin, "
                          "(oprlsortop != 0) AS oprcanmerge, "
                          "oprcanhash "
                          "FROM pg_operator "
                          "WHERE oid = '%u'::oid",
                          oprinfo->dobj.catId.oid);
    }
    else
    {
        appendPQExpBuffer(query, "SELECT oprkind, oprcode, "
                          "CASE WHEN oprleft = 0 THEN '-'::name "
                          "ELSE (SELECT typname FROM pg_type WHERE oid = oprleft) END AS oprleft, "
                          "CASE WHEN oprright = 0 THEN '-'::name "
                          "ELSE (SELECT typname FROM pg_type WHERE oid = oprright) END AS oprright, "
                          "oprcom, oprnegate, oprrest, oprjoin, "
                          "(oprlsortop != 0) AS oprcanmerge, "
                          "oprcanhash "
                          "FROM pg_operator "
                          "WHERE oid = '%u'::oid",
                          oprinfo->dobj.catId.oid);
    }

    res = ExecuteSqlQueryForSingleRow(fout, query->data);

    i_oprkind = PQfnumber(res, "oprkind");
    i_oprcode = PQfnumber(res, "oprcode");
    i_oprleft = PQfnumber(res, "oprleft");
    i_oprright = PQfnumber(res, "oprright");
    i_oprcom = PQfnumber(res, "oprcom");
    i_oprnegate = PQfnumber(res, "oprnegate");
    i_oprrest = PQfnumber(res, "oprrest");
    i_oprjoin = PQfnumber(res, "oprjoin");
    i_oprcanmerge = PQfnumber(res, "oprcanmerge");
    i_oprcanhash = PQfnumber(res, "oprcanhash");

    oprkind = PQgetvalue(res, 0, i_oprkind);
    oprcode = PQgetvalue(res, 0, i_oprcode);
    oprleft = PQgetvalue(res, 0, i_oprleft);
    oprright = PQgetvalue(res, 0, i_oprright);
    oprcom = PQgetvalue(res, 0, i_oprcom);
    oprnegate = PQgetvalue(res, 0, i_oprnegate);
    oprrest = PQgetvalue(res, 0, i_oprrest);
    oprjoin = PQgetvalue(res, 0, i_oprjoin);
    oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
    oprcanhash = PQgetvalue(res, 0, i_oprcanhash);

    appendPQExpBuffer(details, "    PROCEDURE = %s",
                      convertRegProcReference(fout, oprcode));

    appendPQExpBuffer(oprid, "%s (",
                      oprinfo->dobj.name);

    /*
     * right unary means there's a left arg and left unary means there's a
     * right arg
     */
    if (strcmp(oprkind, "r") == 0 ||
        strcmp(oprkind, "b") == 0)
    {
        if (fout->remoteVersion >= 70100)
            name = oprleft;
        else
            name = fmtId(oprleft);
        appendPQExpBuffer(details, ",\n    LEFTARG = %s", name);
        appendPQExpBuffer(oprid, "%s", name);
    }
    else
        appendPQExpBuffer(oprid, "NONE");

    if (strcmp(oprkind, "l") == 0 ||
        strcmp(oprkind, "b") == 0)
    {
        if (fout->remoteVersion >= 70100)
            name = oprright;
        else
            name = fmtId(oprright);
        appendPQExpBuffer(details, ",\n    RIGHTARG = %s", name);
        appendPQExpBuffer(oprid, ", %s)", name);
    }
    else
        appendPQExpBuffer(oprid, ", NONE)");

    name = convertOperatorReference(fout, oprcom);
    if (name)
        appendPQExpBuffer(details, ",\n    COMMUTATOR = %s", name);

    name = convertOperatorReference(fout, oprnegate);
    if (name)
        appendPQExpBuffer(details, ",\n    NEGATOR = %s", name);

    if (strcmp(oprcanmerge, "t") == 0)
        appendPQExpBuffer(details, ",\n    MERGES");

    if (strcmp(oprcanhash, "t") == 0)
        appendPQExpBuffer(details, ",\n    HASHES");

    name = convertRegProcReference(fout, oprrest);
    if (name)
        appendPQExpBuffer(details, ",\n    RESTRICT = %s", name);

    name = convertRegProcReference(fout, oprjoin);
    if (name)
        appendPQExpBuffer(details, ",\n    JOIN = %s", name);

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
                      fmtId(oprinfo->dobj.namespace->dobj.name),
                      oprid->data);

    appendPQExpBuffer(q, "CREATE OPERATOR %s (\n%s\n);\n",
                      oprinfo->dobj.name, details->data);

    appendPQExpBuffer(labelq, "OPERATOR %s", oprid->data);

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &oprinfo->dobj, labelq->data);

    ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
                 oprinfo->dobj.name,
                 oprinfo->dobj.namespace->dobj.name,
                 NULL,
                 oprinfo->rolname,
                 false, "OPERATOR", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Operator Comments */
    dumpComment(fout, labelq->data,
                oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
                oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);

    PQclear(res);

    destroyPQExpBuffer(query);
    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
    destroyPQExpBuffer(oprid);
    destroyPQExpBuffer(details);
}

static void dumpProcLang ( Archive fout,
ProcLangInfo plang 
) [static]

Definition at line 9195 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), binary_upgrade, binary_upgrade_extension_member(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _funcInfo::dobj, _procLangInfo::dobj, _dumpableObject::dump, dumpACL(), dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), _dumpableObject::ext_member, findFuncByOid(), fmtId(), free, _procLangInfo::lanacl, _procLangInfo::laninline, _procLangInfo::lanowner, _procLangInfo::lanplcallfoid, _procLangInfo::lanpltrusted, _procLangInfo::lanvalidator, _dumpableObject::name, NULL, OidIsValid, pg_strdup(), SECTION_PRE_DATA, and shouldDumpProcLangs().

Referenced by dumpDumpableObject().

{
    PQExpBuffer defqry;
    PQExpBuffer delqry;
    PQExpBuffer labelq;
    bool        useParams;
    char       *qlanname;
    char       *lanschema;
    FuncInfo   *funcInfo;
    FuncInfo   *inlineInfo = NULL;
    FuncInfo   *validatorInfo = NULL;

    /* Skip if not to be dumped */
    if (!plang->dobj.dump || dataOnly)
        return;

    /*
     * Try to find the support function(s).  It is not an error if we don't
     * find them --- if the functions are in the pg_catalog schema, as is
     * standard in 8.1 and up, then we won't have loaded them. (In this case
     * we will emit a parameterless CREATE LANGUAGE command, which will
     * require PL template knowledge in the backend to reload.)
     */

    funcInfo = findFuncByOid(plang->lanplcallfoid);
    if (funcInfo != NULL && !funcInfo->dobj.dump)
        funcInfo = NULL;        /* treat not-dumped same as not-found */

    if (OidIsValid(plang->laninline))
    {
        inlineInfo = findFuncByOid(plang->laninline);
        if (inlineInfo != NULL && !inlineInfo->dobj.dump)
            inlineInfo = NULL;
    }

    if (OidIsValid(plang->lanvalidator))
    {
        validatorInfo = findFuncByOid(plang->lanvalidator);
        if (validatorInfo != NULL && !validatorInfo->dobj.dump)
            validatorInfo = NULL;
    }

    /*
     * If the functions are dumpable then emit a traditional CREATE LANGUAGE
     * with parameters.  Otherwise, dump only if shouldDumpProcLangs() says to
     * dump it.
     *
     * However, for a language that belongs to an extension, we must not use
     * the shouldDumpProcLangs heuristic, but just dump the language iff we're
     * told to (via dobj.dump).  Generally the support functions will belong
     * to the same extension and so have the same dump flags ... if they
     * don't, this might not work terribly nicely.
     */
    useParams = (funcInfo != NULL &&
                 (inlineInfo != NULL || !OidIsValid(plang->laninline)) &&
                 (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));

    if (!plang->dobj.ext_member)
    {
        if (!useParams && !shouldDumpProcLangs())
            return;
    }

    defqry = createPQExpBuffer();
    delqry = createPQExpBuffer();
    labelq = createPQExpBuffer();

    qlanname = pg_strdup(fmtId(plang->dobj.name));

    /*
     * If dumping a HANDLER clause, treat the language as being in the handler
     * function's schema; this avoids cluttering the HANDLER clause. Otherwise
     * it doesn't really have a schema.
     */
    if (useParams)
        lanschema = funcInfo->dobj.namespace->dobj.name;
    else
        lanschema = NULL;

    appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
                      qlanname);

    if (useParams)
    {
        appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
                          plang->lanpltrusted ? "TRUSTED " : "",
                          qlanname);
        appendPQExpBuffer(defqry, " HANDLER %s",
                          fmtId(funcInfo->dobj.name));
        if (OidIsValid(plang->laninline))
        {
            appendPQExpBuffer(defqry, " INLINE ");
            /* Cope with possibility that inline is in different schema */
            if (inlineInfo->dobj.namespace != funcInfo->dobj.namespace)
                appendPQExpBuffer(defqry, "%s.",
                               fmtId(inlineInfo->dobj.namespace->dobj.name));
            appendPQExpBuffer(defqry, "%s",
                              fmtId(inlineInfo->dobj.name));
        }
        if (OidIsValid(plang->lanvalidator))
        {
            appendPQExpBuffer(defqry, " VALIDATOR ");
            /* Cope with possibility that validator is in different schema */
            if (validatorInfo->dobj.namespace != funcInfo->dobj.namespace)
                appendPQExpBuffer(defqry, "%s.",
                            fmtId(validatorInfo->dobj.namespace->dobj.name));
            appendPQExpBuffer(defqry, "%s",
                              fmtId(validatorInfo->dobj.name));
        }
    }
    else
    {
        /*
         * If not dumping parameters, then use CREATE OR REPLACE so that the
         * command will not fail if the language is preinstalled in the target
         * database.  We restrict the use of REPLACE to this case so as to
         * eliminate the risk of replacing a language with incompatible
         * parameter settings: this command will only succeed at all if there
         * is a pg_pltemplate entry, and if there is one, the existing entry
         * must match it too.
         */
        appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s",
                          qlanname);
    }
    appendPQExpBuffer(defqry, ";\n");

    appendPQExpBuffer(labelq, "LANGUAGE %s", qlanname);

    if (binary_upgrade)
        binary_upgrade_extension_member(defqry, &plang->dobj, labelq->data);

    ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
                 plang->dobj.name,
                 lanschema, NULL, plang->lanowner,
                 false, "PROCEDURAL LANGUAGE", SECTION_PRE_DATA,
                 defqry->data, delqry->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Proc Lang Comments and Security Labels */
    dumpComment(fout, labelq->data,
                NULL, "",
                plang->dobj.catId, 0, plang->dobj.dumpId);
    dumpSecLabel(fout, labelq->data,
                 NULL, "",
                 plang->dobj.catId, 0, plang->dobj.dumpId);

    if (plang->lanpltrusted)
        dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId, "LANGUAGE",
                qlanname, NULL, plang->dobj.name,
                lanschema,
                plang->lanowner, plang->lanacl);

    free(qlanname);

    destroyPQExpBuffer(defqry);
    destroyPQExpBuffer(delqry);
    destroyPQExpBuffer(labelq);
}

static void dumpRangeType ( Archive fout,
TypeInfo tyinfo 
) [static]

Definition at line 8107 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), atooid, binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_type_oids_by_type_oid(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _collInfo::dobj, dumpACL(), dumpComment(), dumpSecLabel(), ExecuteSqlQueryForSingleRow(), findCollationByOid(), fmtId(), _dumpableObject::name, NULL, OidIsValid, pg_strdup(), PQclear(), PQfnumber(), PQgetvalue(), SECTION_PRE_DATA, and selectSourceSchema().

Referenced by dumpType().

{
    PQExpBuffer q = createPQExpBuffer();
    PQExpBuffer delq = createPQExpBuffer();
    PQExpBuffer labelq = createPQExpBuffer();
    PQExpBuffer query = createPQExpBuffer();
    PGresult   *res;
    Oid         collationOid;
    char       *qtypname;
    char       *procname;

    /*
     * select appropriate schema to ensure names in CREATE are properly
     * qualified
     */
    selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);

    appendPQExpBuffer(query,
            "SELECT pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
                      "opc.opcname AS opcname, "
                      "(SELECT nspname FROM pg_catalog.pg_namespace nsp "
                      "  WHERE nsp.oid = opc.opcnamespace) AS opcnsp, "
                      "opc.opcdefault, "
                      "CASE WHEN rngcollation = st.typcollation THEN 0 "
                      "     ELSE rngcollation END AS collation, "
                      "rngcanonical, rngsubdiff "
                      "FROM pg_catalog.pg_range r, pg_catalog.pg_type st, "
                      "     pg_catalog.pg_opclass opc "
                      "WHERE st.oid = rngsubtype AND opc.oid = rngsubopc AND "
                      "rngtypid = '%u'",
                      tyinfo->dobj.catId.oid);

    res = ExecuteSqlQueryForSingleRow(fout, query->data);

    qtypname = pg_strdup(fmtId(tyinfo->dobj.name));

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog.
     * CASCADE shouldn't be required here as for normal types since the I/O
     * functions are generic and do not get dropped.
     */
    appendPQExpBuffer(delq, "DROP TYPE %s.",
                      fmtId(tyinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delq, "%s;\n",
                      qtypname);

    if (binary_upgrade)
        binary_upgrade_set_type_oids_by_type_oid(fout,
                                                 q, tyinfo->dobj.catId.oid);

    appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
                      qtypname);

    appendPQExpBuffer(q, "\n    subtype = %s",
                      PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));

    /* print subtype_opclass only if not default for subtype */
    if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't')
    {
        char       *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
        char       *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));

        /* always schema-qualify, don't try to be smart */
        appendPQExpBuffer(q, ",\n    subtype_opclass = %s.",
                          fmtId(nspname));
        appendPQExpBuffer(q, "%s", fmtId(opcname));
    }

    collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation")));
    if (OidIsValid(collationOid))
    {
        CollInfo   *coll = findCollationByOid(collationOid);

        if (coll)
        {
            /* always schema-qualify, don't try to be smart */
            appendPQExpBuffer(q, ",\n    collation = %s.",
                              fmtId(coll->dobj.namespace->dobj.name));
            appendPQExpBuffer(q, "%s",
                              fmtId(coll->dobj.name));
        }
    }

    procname = PQgetvalue(res, 0, PQfnumber(res, "rngcanonical"));
    if (strcmp(procname, "-") != 0)
        appendPQExpBuffer(q, ",\n    canonical = %s", procname);

    procname = PQgetvalue(res, 0, PQfnumber(res, "rngsubdiff"));
    if (strcmp(procname, "-") != 0)
        appendPQExpBuffer(q, ",\n    subtype_diff = %s", procname);

    appendPQExpBuffer(q, "\n);\n");

    appendPQExpBuffer(labelq, "TYPE %s", qtypname);

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);

    ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
                 tyinfo->dobj.name,
                 tyinfo->dobj.namespace->dobj.name,
                 NULL,
                 tyinfo->rolname, false,
                 "TYPE", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump Type Comments and Security Labels */
    dumpComment(fout, labelq->data,
                tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
    dumpSecLabel(fout, labelq->data,
                 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);

    dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
            qtypname, NULL, tyinfo->dobj.name,
            tyinfo->dobj.namespace->dobj.name,
            tyinfo->rolname, tyinfo->typacl);

    PQclear(res);
    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
    destroyPQExpBuffer(query);
}

static void dumpRule ( Archive fout,
RuleInfo rinfo 
) [static]

Definition at line 14367 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _ruleInfo::dobj, _dumpableObject::dump, dumpComment(), _dumpableObject::dumpId, _ruleInfo::ev_enabled, ExecuteSqlQuery(), exit_nicely, fmtId(), _dumpableObject::name, NULL, CatalogId::oid, PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), _ruleInfo::reloptions, Archive::remoteVersion, _tableInfo::rolname, _ruleInfo::ruletable, SECTION_POST_DATA, selectSourceSchema(), _ruleInfo::separate, and write_msg().

Referenced by dumpDumpableObject().

{
    TableInfo  *tbinfo = rinfo->ruletable;
    PQExpBuffer query;
    PQExpBuffer cmd;
    PQExpBuffer delcmd;
    PQExpBuffer labelq;
    PGresult   *res;

    /* Skip if not to be dumped */
    if (!rinfo->dobj.dump || dataOnly)
        return;

    /*
     * If it is an ON SELECT rule that is created implicitly by CREATE VIEW,
     * we do not want to dump it as a separate object.
     */
    if (!rinfo->separate)
        return;

    /*
     * Make sure we are in proper schema.
     */
    selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);

    query = createPQExpBuffer();
    cmd = createPQExpBuffer();
    delcmd = createPQExpBuffer();
    labelq = createPQExpBuffer();

    if (fout->remoteVersion >= 70300)
    {
        appendPQExpBuffer(query,
                          "SELECT pg_catalog.pg_get_ruledef('%u'::pg_catalog.oid) AS definition",
                          rinfo->dobj.catId.oid);
    }
    else
    {
        /* Rule name was unique before 7.3 ... */
        appendPQExpBuffer(query,
                          "SELECT pg_get_ruledef('%s') AS definition",
                          rinfo->dobj.name);
    }

    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    if (PQntuples(res) != 1)
    {
        write_msg(NULL, "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned\n",
                  rinfo->dobj.name, tbinfo->dobj.name);
        exit_nicely(1);
    }

    printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));

    /*
     * Add the command to alter the rules replication firing semantics if it
     * differs from the default.
     */
    if (rinfo->ev_enabled != 'O')
    {
        appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtId(tbinfo->dobj.name));
        switch (rinfo->ev_enabled)
        {
            case 'A':
                appendPQExpBuffer(cmd, "ENABLE ALWAYS RULE %s;\n",
                                  fmtId(rinfo->dobj.name));
                break;
            case 'R':
                appendPQExpBuffer(cmd, "ENABLE REPLICA RULE %s;\n",
                                  fmtId(rinfo->dobj.name));
                break;
            case 'D':
                appendPQExpBuffer(cmd, "DISABLE RULE %s;\n",
                                  fmtId(rinfo->dobj.name));
                break;
        }
    }

    /*
     * Apply view's reloptions when its ON SELECT rule is separate.
     */
    if (rinfo->reloptions && strlen(rinfo->reloptions) > 0)
    {
        appendPQExpBuffer(cmd, "ALTER VIEW %s SET (%s);\n",
                          fmtId(tbinfo->dobj.name),
                          rinfo->reloptions);
    }

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delcmd, "DROP RULE %s ",
                      fmtId(rinfo->dobj.name));
    appendPQExpBuffer(delcmd, "ON %s.",
                      fmtId(tbinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delcmd, "%s;\n",
                      fmtId(tbinfo->dobj.name));

    appendPQExpBuffer(labelq, "RULE %s",
                      fmtId(rinfo->dobj.name));
    appendPQExpBuffer(labelq, " ON %s",
                      fmtId(tbinfo->dobj.name));

    ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId,
                 rinfo->dobj.name,
                 tbinfo->dobj.namespace->dobj.name,
                 NULL,
                 tbinfo->rolname, false,
                 "RULE", SECTION_POST_DATA,
                 cmd->data, delcmd->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /* Dump rule comments */
    dumpComment(fout, labelq->data,
                tbinfo->dobj.namespace->dobj.name,
                tbinfo->rolname,
                rinfo->dobj.catId, 0, rinfo->dobj.dumpId);

    PQclear(res);

    destroyPQExpBuffer(query);
    destroyPQExpBuffer(cmd);
    destroyPQExpBuffer(delcmd);
    destroyPQExpBuffer(labelq);
}

static void dumpSecLabel ( Archive fout,
const char *  target,
const char *  namespace,
const char *  owner,
CatalogId  catalogId,
int  subid,
DumpId  dumpId 
) [static]

Definition at line 12379 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), findSecLabels(), fmtId(), i, label, PQExpBufferData::len, no_security_labels, NULL, CatalogId::oid, schemaOnly, SECTION_NONE, and CatalogId::tableoid.

Referenced by dumpAgg(), dumpBaseType(), dumpBlob(), dumpCompositeType(), dumpDomain(), dumpEnumType(), dumpExtension(), dumpFunc(), dumpNamespace(), dumpProcLang(), dumpRangeType(), and dumpSequence().

{
    SecLabelItem *labels;
    int         nlabels;
    int         i;
    PQExpBuffer query;

    /* do nothing, if --no-security-labels is supplied */
    if (no_security_labels)
        return;

    /* Comments are schema not data ... except blob comments are data */
    if (strncmp(target, "LARGE OBJECT ", 13) != 0)
    {
        if (dataOnly)
            return;
    }
    else
    {
        if (schemaOnly)
            return;
    }

    /* Search for security labels associated with catalogId, using table */
    nlabels = findSecLabels(fout, catalogId.tableoid, catalogId.oid, &labels);

    query = createPQExpBuffer();

    for (i = 0; i < nlabels; i++)
    {
        /*
         * Ignore label entries for which the subid doesn't match.
         */
        if (labels[i].objsubid != subid)
            continue;

        appendPQExpBuffer(query,
                          "SECURITY LABEL FOR %s ON %s IS ",
                          fmtId(labels[i].provider), target);
        appendStringLiteralAH(query, labels[i].label, fout);
        appendPQExpBuffer(query, ";\n");
    }

    if (query->len > 0)
    {
        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                     target, namespace, NULL, owner,
                     false, "SECURITY LABEL", SECTION_NONE,
                     query->data, "", NULL,
                     &(dumpId), 1,
                     NULL, NULL);
    }
    destroyPQExpBuffer(query);
}

static void dumpSequence ( Archive fout,
TableInfo tbinfo 
) [static]

Definition at line 13842 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), _tableInfo::attnames, binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_pg_class_oids(), binary_upgrade_set_type_oids_by_rel_oid(), _dumpableObject::catId, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _dumpableObject::dump, dumpComment(), _dumpableObject::dumpId, dumpSecLabel(), ExecuteSqlQuery(), exit_nicely, findTableByOid(), fmtId(), _dumpableObject::name, ngettext, NULL, CatalogId::oid, OidIsValid, _tableInfo::owning_col, _tableInfo::owning_tab, PGRES_TUPLES_OK, PQclear(), PQgetisnull(), PQgetvalue(), PQntuples(), Archive::remoteVersion, resetPQExpBuffer(), _tableInfo::rolname, SECTION_PRE_DATA, selectSourceSchema(), SEQ_MAXVALUE, SEQ_MINVALUE, snprintf(), and write_msg().

Referenced by dumpTable().

{
    PGresult   *res;
    char       *startv,
               *incby,
               *maxv = NULL,
               *minv = NULL,
               *cache;
    char        bufm[100],
                bufx[100];
    bool        cycled;
    PQExpBuffer query = createPQExpBuffer();
    PQExpBuffer delqry = createPQExpBuffer();
    PQExpBuffer labelq = createPQExpBuffer();

    /* Make sure we are in proper schema */
    selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);

    snprintf(bufm, sizeof(bufm), INT64_FORMAT, SEQ_MINVALUE);
    snprintf(bufx, sizeof(bufx), INT64_FORMAT, SEQ_MAXVALUE);

    if (fout->remoteVersion >= 80400)
    {
        appendPQExpBuffer(query,
                          "SELECT sequence_name, "
                          "start_value, increment_by, "
                   "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
                   "     WHEN increment_by < 0 AND max_value = -1 THEN NULL "
                          "     ELSE max_value "
                          "END AS max_value, "
                    "CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
                   "     WHEN increment_by < 0 AND min_value = %s THEN NULL "
                          "     ELSE min_value "
                          "END AS min_value, "
                          "cache_value, is_cycled FROM %s",
                          bufx, bufm,
                          fmtId(tbinfo->dobj.name));
    }
    else
    {
        appendPQExpBuffer(query,
                          "SELECT sequence_name, "
                          "0 AS start_value, increment_by, "
                   "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
                   "     WHEN increment_by < 0 AND max_value = -1 THEN NULL "
                          "     ELSE max_value "
                          "END AS max_value, "
                    "CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
                   "     WHEN increment_by < 0 AND min_value = %s THEN NULL "
                          "     ELSE min_value "
                          "END AS min_value, "
                          "cache_value, is_cycled FROM %s",
                          bufx, bufm,
                          fmtId(tbinfo->dobj.name));
    }

    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    if (PQntuples(res) != 1)
    {
        write_msg(NULL, ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)\n",
                                 "query to get data of sequence \"%s\" returned %d rows (expected 1)\n",
                                 PQntuples(res)),
                  tbinfo->dobj.name, PQntuples(res));
        exit_nicely(1);
    }

    /* Disable this check: it fails if sequence has been renamed */
#ifdef NOT_USED
    if (strcmp(PQgetvalue(res, 0, 0), tbinfo->dobj.name) != 0)
    {
        write_msg(NULL, "query to get data of sequence \"%s\" returned name \"%s\"\n",
                  tbinfo->dobj.name, PQgetvalue(res, 0, 0));
        exit_nicely(1);
    }
#endif

    startv = PQgetvalue(res, 0, 1);
    incby = PQgetvalue(res, 0, 2);
    if (!PQgetisnull(res, 0, 3))
        maxv = PQgetvalue(res, 0, 3);
    if (!PQgetisnull(res, 0, 4))
        minv = PQgetvalue(res, 0, 4);
    cache = PQgetvalue(res, 0, 5);
    cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);

    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
     */
    appendPQExpBuffer(delqry, "DROP SEQUENCE %s.",
                      fmtId(tbinfo->dobj.namespace->dobj.name));
    appendPQExpBuffer(delqry, "%s;\n",
                      fmtId(tbinfo->dobj.name));

    resetPQExpBuffer(query);

    if (binary_upgrade)
    {
        binary_upgrade_set_pg_class_oids(fout, query,
                                         tbinfo->dobj.catId.oid, false);
        binary_upgrade_set_type_oids_by_rel_oid(fout, query,
                                                tbinfo->dobj.catId.oid);
    }

    appendPQExpBuffer(query,
                      "CREATE SEQUENCE %s\n",
                      fmtId(tbinfo->dobj.name));

    if (fout->remoteVersion >= 80400)
        appendPQExpBuffer(query, "    START WITH %s\n", startv);

    appendPQExpBuffer(query, "    INCREMENT BY %s\n", incby);

    if (minv)
        appendPQExpBuffer(query, "    MINVALUE %s\n", minv);
    else
        appendPQExpBuffer(query, "    NO MINVALUE\n");

    if (maxv)
        appendPQExpBuffer(query, "    MAXVALUE %s\n", maxv);
    else
        appendPQExpBuffer(query, "    NO MAXVALUE\n");

    appendPQExpBuffer(query,
                      "    CACHE %s%s",
                      cache, (cycled ? "\n    CYCLE" : ""));

    appendPQExpBuffer(query, ";\n");

    appendPQExpBuffer(labelq, "SEQUENCE %s", fmtId(tbinfo->dobj.name));

    /* binary_upgrade:  no need to clear TOAST table oid */

    if (binary_upgrade)
        binary_upgrade_extension_member(query, &tbinfo->dobj,
                                        labelq->data);

    ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
                 tbinfo->dobj.name,
                 tbinfo->dobj.namespace->dobj.name,
                 NULL,
                 tbinfo->rolname,
                 false, "SEQUENCE", SECTION_PRE_DATA,
                 query->data, delqry->data, NULL,
                 NULL, 0,
                 NULL, NULL);

    /*
     * If the sequence is owned by a table column, emit the ALTER for it as a
     * separate TOC entry immediately following the sequence's own entry. It's
     * OK to do this rather than using full sorting logic, because the
     * dependency that tells us it's owned will have forced the table to be
     * created first.  We can't just include the ALTER in the TOC entry
     * because it will fail if we haven't reassigned the sequence owner to
     * match the table's owner.
     *
     * We need not schema-qualify the table reference because both sequence
     * and table must be in the same schema.
     */
    if (OidIsValid(tbinfo->owning_tab))
    {
        TableInfo  *owning_tab = findTableByOid(tbinfo->owning_tab);

        if (owning_tab && owning_tab->dobj.dump)
        {
            resetPQExpBuffer(query);
            appendPQExpBuffer(query, "ALTER SEQUENCE %s",
                              fmtId(tbinfo->dobj.name));
            appendPQExpBuffer(query, " OWNED BY %s",
                              fmtId(owning_tab->dobj.name));
            appendPQExpBuffer(query, ".%s;\n",
                        fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));

            ArchiveEntry(fout, nilCatalogId, createDumpId(),
                         tbinfo->dobj.name,
                         tbinfo->dobj.namespace->dobj.name,
                         NULL,
                         tbinfo->rolname,
                         false, "SEQUENCE OWNED BY", SECTION_PRE_DATA,
                         query->data, "", NULL,
                         &(tbinfo->dobj.dumpId), 1,
                         NULL, NULL);
        }
    }

    /* Dump Sequence Comments and Security Labels */
    dumpComment(fout, labelq->data,
                tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
    dumpSecLabel(fout, labelq->data,
                 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                 tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);

    PQclear(res);

    destroyPQExpBuffer(query);
    destroyPQExpBuffer(delqry);
    destroyPQExpBuffer(labelq);
}

static void dumpSequenceData ( Archive fout,
TableDataInfo tdinfo 
) [static]

Definition at line 14047 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, _dumpableObject::dumpId, ExecuteSqlQuery(), exit_nicely, fmtId(), _dumpableObject::name, ngettext, NULL, PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), resetPQExpBuffer(), _tableInfo::rolname, SECTION_DATA, selectSourceSchema(), _tableDataInfo::tdtable, and write_msg().

Referenced by dumpDumpableObject().

{
    TableInfo  *tbinfo = tdinfo->tdtable;
    PGresult   *res;
    char       *last;
    bool        called;
    PQExpBuffer query = createPQExpBuffer();

    /* Make sure we are in proper schema */
    selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);

    appendPQExpBuffer(query,
                      "SELECT last_value, is_called FROM %s",
                      fmtId(tbinfo->dobj.name));

    res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

    if (PQntuples(res) != 1)
    {
        write_msg(NULL, ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)\n",
                                 "query to get data of sequence \"%s\" returned %d rows (expected 1)\n",
                                 PQntuples(res)),
                  tbinfo->dobj.name, PQntuples(res));
        exit_nicely(1);
    }

    last = PQgetvalue(res, 0, 0);
    called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);

    resetPQExpBuffer(query);
    appendPQExpBuffer(query, "SELECT pg_catalog.setval(");
    appendStringLiteralAH(query, fmtId(tbinfo->dobj.name), fout);
    appendPQExpBuffer(query, ", %s, %s);\n",
                      last, (called ? "true" : "false"));

    ArchiveEntry(fout, nilCatalogId, createDumpId(),
                 tbinfo->dobj.name,
                 tbinfo->dobj.namespace->dobj.name,
                 NULL,
                 tbinfo->rolname,
                 false, "SEQUENCE SET", SECTION_DATA,
                 query->data, "", NULL,
                 &(tbinfo->dobj.dumpId), 1,
                 NULL, NULL);

    PQclear(res);

    destroyPQExpBuffer(query);
}

static void dumpShellType ( Archive fout,
ShellTypeInfo stinfo 
) [static]

Definition at line 9124 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), _shellTypeInfo::baseType, binary_upgrade, binary_upgrade_set_type_oids_by_type_oid(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _shellTypeInfo::dobj, _dumpableObject::dump, _dumpableObject::dumpId, fmtId(), _dumpableObject::name, NULL, and SECTION_PRE_DATA.

Referenced by dumpDumpableObject().

{
    PQExpBuffer q;

    /* Skip if not to be dumped */
    if (!stinfo->dobj.dump || dataOnly)
        return;

    q = createPQExpBuffer();

    /*
     * Note the lack of a DROP command for the shell type; any required DROP
     * is driven off the base type entry, instead.  This interacts with
     * _printTocEntry()'s use of the presence of a DROP command to decide
     * whether an entry needs an ALTER OWNER command.  We don't want to alter
     * the shell type's owner immediately on creation; that should happen only
     * after it's filled in, otherwise the backend complains.
     */

    if (binary_upgrade)
        binary_upgrade_set_type_oids_by_type_oid(fout, q,
                                           stinfo->baseType->dobj.catId.oid);

    appendPQExpBuffer(q, "CREATE TYPE %s;\n",
                      fmtId(stinfo->dobj.name));

    ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
                 stinfo->dobj.name,
                 stinfo->dobj.namespace->dobj.name,
                 NULL,
                 stinfo->baseType->rolname, false,
                 "SHELL TYPE", SECTION_PRE_DATA,
                 q->data, "", NULL,
                 NULL, 0,
                 NULL, NULL);

    destroyPQExpBuffer(q);
}

static void dumpStdStrings ( Archive AH  )  [static]

Definition at line 2453 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), createDumpId(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), g_verbose, NULL, SECTION_PRE_DATA, Archive::std_strings, and write_msg().

Referenced by main().

{
    const char *stdstrings = AH->std_strings ? "on" : "off";
    PQExpBuffer qry = createPQExpBuffer();

    if (g_verbose)
        write_msg(NULL, "saving standard_conforming_strings = %s\n",
                  stdstrings);

    appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
                      stdstrings);

    ArchiveEntry(AH, nilCatalogId, createDumpId(),
                 "STDSTRINGS", NULL, NULL, "",
                 false, "STDSTRINGS", SECTION_PRE_DATA,
                 qry->data, "", NULL,
                 NULL, 0,
                 NULL, NULL);

    destroyPQExpBuffer(qry);
}

static void dumpTable ( Archive fout,
TableInfo tbinfo 
) [static]

Definition at line 12664 of file pg_dump.c.

References appendPQExpBuffer(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _dumpableObject::dump, dumpACL(), _dumpableObject::dumpId, dumpSequence(), dumpTableSchema(), ExecuteSqlQuery(), fmtId(), free, i, _dumpableObject::name, NULL, CatalogId::oid, pg_malloc(), pg_strdup(), PGRES_TUPLES_OK, PQclear(), PQgetvalue(), PQntuples(), _tableInfo::relacl, _tableInfo::relkind, RELKIND_SEQUENCE, Archive::remoteVersion, and _tableInfo::rolname.

Referenced by dumpDumpableObject().

{
    if (tbinfo->dobj.dump && !dataOnly)
    {
        char       *namecopy;

        if (tbinfo->relkind == RELKIND_SEQUENCE)
            dumpSequence(fout, tbinfo);
        else
            dumpTableSchema(fout, tbinfo);

        /* Handle the ACL here */
        namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
        dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
                (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" :
                "TABLE",
                namecopy, NULL, tbinfo->dobj.name,
                tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                tbinfo->relacl);

        /*
         * Handle column ACLs, if any.  Note: we pull these with a separate
         * query rather than trying to fetch them during getTableAttrs, so
         * that we won't miss ACLs on system columns.
         */
        if (fout->remoteVersion >= 80400)
        {
            PQExpBuffer query = createPQExpBuffer();
            PGresult   *res;
            int         i;

            appendPQExpBuffer(query,
                       "SELECT attname, attacl FROM pg_catalog.pg_attribute "
                              "WHERE attrelid = '%u' AND NOT attisdropped AND attacl IS NOT NULL "
                              "ORDER BY attnum",
                              tbinfo->dobj.catId.oid);
            res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

            for (i = 0; i < PQntuples(res); i++)
            {
                char       *attname = PQgetvalue(res, i, 0);
                char       *attacl = PQgetvalue(res, i, 1);
                char       *attnamecopy;
                char       *acltag;

                attnamecopy = pg_strdup(fmtId(attname));
                acltag = pg_malloc(strlen(tbinfo->dobj.name) + strlen(attname) + 2);
                sprintf(acltag, "%s.%s", tbinfo->dobj.name, attname);
                /* Column's GRANT type is always TABLE */
                dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, "TABLE",
                        namecopy, attnamecopy, acltag,
                        tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                        attacl);
                free(attnamecopy);
                free(acltag);
            }
            PQclear(res);
            destroyPQExpBuffer(query);
        }

        free(namecopy);
    }
}

static void dumpTableComment ( Archive fout,
TableInfo tbinfo,
const char *  reltypename 
) [static]

Definition at line 7386 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), _tableInfo::attnames, _dumpableObject::catId, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, dataOnly, CommentItem::descr, destroyPQExpBuffer(), _tableInfo::dobj, _dumpableObject::dumpId, findComments(), fmtId(), _dumpableObject::name, NULL, CommentItem::objsubid, CatalogId::oid, resetPQExpBuffer(), _tableInfo::rolname, SECTION_NONE, and CatalogId::tableoid.

Referenced by dumpTableSchema().

{
    CommentItem *comments;
    int         ncomments;
    PQExpBuffer query;
    PQExpBuffer target;

    /* Comments are SCHEMA not data */
    if (dataOnly)
        return;

    /* Search for comments associated with relation, using table */
    ncomments = findComments(fout,
                             tbinfo->dobj.catId.tableoid,
                             tbinfo->dobj.catId.oid,
                             &comments);

    /* If comments exist, build COMMENT ON statements */
    if (ncomments <= 0)
        return;

    query = createPQExpBuffer();
    target = createPQExpBuffer();

    while (ncomments > 0)
    {
        const char *descr = comments->descr;
        int         objsubid = comments->objsubid;

        if (objsubid == 0)
        {
            resetPQExpBuffer(target);
            appendPQExpBuffer(target, "%s %s", reltypename,
                              fmtId(tbinfo->dobj.name));

            resetPQExpBuffer(query);
            appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
            appendStringLiteralAH(query, descr, fout);
            appendPQExpBuffer(query, ";\n");

            ArchiveEntry(fout, nilCatalogId, createDumpId(),
                         target->data,
                         tbinfo->dobj.namespace->dobj.name,
                         NULL, tbinfo->rolname,
                         false, "COMMENT", SECTION_NONE,
                         query->data, "", NULL,
                         &(tbinfo->dobj.dumpId), 1,
                         NULL, NULL);
        }
        else if (objsubid > 0 && objsubid <= tbinfo->numatts)
        {
            resetPQExpBuffer(target);
            appendPQExpBuffer(target, "COLUMN %s.",
                              fmtId(tbinfo->dobj.name));
            appendPQExpBuffer(target, "%s",
                              fmtId(tbinfo->attnames[objsubid - 1]));

            resetPQExpBuffer(query);
            appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
            appendStringLiteralAH(query, descr, fout);
            appendPQExpBuffer(query, ";\n");

            ArchiveEntry(fout, nilCatalogId, createDumpId(),
                         target->data,
                         tbinfo->dobj.namespace->dobj.name,
                         NULL, tbinfo->rolname,
                         false, "COMMENT", SECTION_NONE,
                         query->data, "", NULL,
                         &(tbinfo->dobj.dumpId), 1,
                         NULL, NULL);
        }

        comments++;
        ncomments--;
    }

    destroyPQExpBuffer(query);
    destroyPQExpBuffer(target);
}

static void dumpTableConstraintComment ( Archive fout,
ConstraintInfo coninfo 
) [static]
static void dumpTableData ( Archive fout,
TableDataInfo tdinfo 
) [static]

Definition at line 1704 of file pg_dump.c.

References appendPQExpBuffer(), ArchiveEntry(), _dumpableObject::catId, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableDataInfo::dobj, _tableInfo::dobj, dump_inserts, _dumpableObject::dumpId, fmtCopyColumnList(), fmtId(), _tableInfo::hasoids, _dumpableObject::name, NULL, _tableDataInfo::oids, _tableInfo::rolname, SECTION_DATA, and _tableDataInfo::tdtable.

Referenced by dumpDumpableObject().

{
    TableInfo  *tbinfo = tdinfo->tdtable;
    PQExpBuffer copyBuf = createPQExpBuffer();
    PQExpBuffer clistBuf = createPQExpBuffer();
    DataDumperPtr dumpFn;
    char       *copyStmt;

    if (!dump_inserts)
    {
        /* Dump/restore using COPY */
        dumpFn = dumpTableData_copy;
        /* must use 2 steps here 'cause fmtId is nonreentrant */
        appendPQExpBuffer(copyBuf, "COPY %s ",
                          fmtId(tbinfo->dobj.name));
        appendPQExpBuffer(copyBuf, "%s %sFROM stdin;\n",
                          fmtCopyColumnList(tbinfo, clistBuf),
                      (tdinfo->oids && tbinfo->hasoids) ? "WITH OIDS " : "");
        copyStmt = copyBuf->data;
    }
    else
    {
        /* Restore using INSERT */
        dumpFn = dumpTableData_insert;
        copyStmt = NULL;
    }

    /*
     * Note: although the TableDataInfo is a full DumpableObject, we treat its
     * dependency on its table as "special" and pass it to ArchiveEntry now.
     * See comments for BuildArchiveDependencies.
     */
    ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
                 tbinfo->dobj.name, tbinfo->dobj.namespace->dobj.name,
                 NULL, tbinfo->rolname,
                 false, "TABLE DATA", SECTION_DATA,
                 "", "", copyStmt,
                 &(tbinfo->dobj.dumpId), 1,
                 dumpFn, tdinfo);

    destroyPQExpBuffer(copyBuf);
    destroyPQExpBuffer(clistBuf);
}

static int dumpTableData_copy ( Archive fout,
void *  dcontext 
) [static]

Definition at line 1371 of file pg_dump.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), archprintf(), conn, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, ExecuteSqlQuery(), exit_nicely, _tableDataInfo::filtercond, fmtCopyColumnList(), fmtQualifiedId(), g_verbose, GetConnection(), _tableInfo::hasoids, PQExpBufferData::len, _dumpableObject::name, NULL, _tableDataInfo::oids, PGRES_COMMAND_OK, PGRES_COPY_OUT, PQclear(), PQerrorMessage(), PQfreemem(), PQgetCopyData(), PQgetResult(), PQresultStatus(), Archive::remoteVersion, selectSourceSchema(), _tableDataInfo::tdtable, write_msg(), and WriteData().

{
    TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
    TableInfo  *tbinfo = tdinfo->tdtable;
    const char *classname = tbinfo->dobj.name;
    const bool  hasoids = tbinfo->hasoids;
    const bool  oids = tdinfo->oids;
    PQExpBuffer q = createPQExpBuffer();

    /*
     * Note: can't use getThreadLocalPQExpBuffer() here, we're calling fmtId
     * which uses it already.
     */
    PQExpBuffer clistBuf = createPQExpBuffer();
    PGconn     *conn = GetConnection(fout);
    PGresult   *res;
    int         ret;
    char       *copybuf;
    const char *column_list;

    if (g_verbose)
        write_msg(NULL, "dumping contents of table %s\n", classname);

    /*
     * Make sure we are in proper schema.  We will qualify the table name
     * below anyway (in case its name conflicts with a pg_catalog table); but
     * this ensures reproducible results in case the table contains regproc,
     * regclass, etc columns.
     */
    selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);

    /*
     * If possible, specify the column list explicitly so that we have no
     * possibility of retrieving data in the wrong column order.  (The default
     * column ordering of COPY will not be what we want in certain corner
     * cases involving ADD COLUMN and inheritance.)
     */
    if (fout->remoteVersion >= 70300)
        column_list = fmtCopyColumnList(tbinfo, clistBuf);
    else
        column_list = "";       /* can't select columns in COPY */

    if (oids && hasoids)
    {
        appendPQExpBuffer(q, "COPY %s %s WITH OIDS TO stdout;",
                          fmtQualifiedId(fout->remoteVersion,
                                         tbinfo->dobj.namespace->dobj.name,
                                         classname),
                          column_list);
    }
    else if (tdinfo->filtercond)
    {
        /* Note: this syntax is only supported in 8.2 and up */
        appendPQExpBufferStr(q, "COPY (SELECT ");
        /* klugery to get rid of parens in column list */
        if (strlen(column_list) > 2)
        {
            appendPQExpBufferStr(q, column_list + 1);
            q->data[q->len - 1] = ' ';
        }
        else
            appendPQExpBufferStr(q, "* ");
        appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
                          fmtQualifiedId(fout->remoteVersion,
                                         tbinfo->dobj.namespace->dobj.name,
                                         classname),
                          tdinfo->filtercond);
    }
    else
    {
        appendPQExpBuffer(q, "COPY %s %s TO stdout;",
                          fmtQualifiedId(fout->remoteVersion,
                                         tbinfo->dobj.namespace->dobj.name,
                                         classname),
                          column_list);
    }
    res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
    PQclear(res);
    destroyPQExpBuffer(clistBuf);

    for (;;)
    {
        ret = PQgetCopyData(conn, &copybuf, 0);

        if (ret < 0)
            break;              /* done or error */

        if (copybuf)
        {
            WriteData(fout, copybuf, ret);
            PQfreemem(copybuf);
        }

        /* ----------
         * THROTTLE:
         *
         * There was considerable discussion in late July, 2000 regarding
         * slowing down pg_dump when backing up large tables. Users with both
         * slow & fast (multi-processor) machines experienced performance
         * degradation when doing a backup.
         *
         * Initial attempts based on sleeping for a number of ms for each ms
         * of work were deemed too complex, then a simple 'sleep in each loop'
         * implementation was suggested. The latter failed because the loop
         * was too tight. Finally, the following was implemented:
         *
         * If throttle is non-zero, then
         *      See how long since the last sleep.
         *      Work out how long to sleep (based on ratio).
         *      If sleep is more than 100ms, then
         *          sleep
         *          reset timer
         *      EndIf
         * EndIf
         *
         * where the throttle value was the number of ms to sleep per ms of
         * work. The calculation was done in each loop.
         *
         * Most of the hard work is done in the backend, and this solution
         * still did not work particularly well: on slow machines, the ratio
         * was 50:1, and on medium paced machines, 1:1, and on fast
         * multi-processor machines, it had little or no effect, for reasons
         * that were unclear.
         *
         * Further discussion ensued, and the proposal was dropped.
         *
         * For those people who want this feature, it can be implemented using
         * gettimeofday in each loop, calculating the time since last sleep,
         * multiplying that by the sleep ratio, then if the result is more
         * than a preset 'minimum sleep time' (say 100ms), call the 'select'
         * function to sleep for a subsecond period ie.
         *
         * select(0, NULL, NULL, NULL, &tvi);
         *
         * This will return after the interval specified in the structure tvi.
         * Finally, call gettimeofday again to save the 'last sleep time'.
         * ----------
         */
    }
    archprintf(fout, "\\.\n\n\n");

    if (ret == -2)
    {
        /* copy data transfer failed */
        write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n", classname);
        write_msg(NULL, "Error message from server: %s", PQerrorMessage(conn));
        write_msg(NULL, "The command was: %s\n", q->data);
        exit_nicely(1);
    }

    /* Check command status and return to normal libpq state */
    res = PQgetResult(conn);
    if (PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n", classname);
        write_msg(NULL, "Error message from server: %s", PQerrorMessage(conn));
        write_msg(NULL, "The command was: %s\n", q->data);
        exit_nicely(1);
    }
    PQclear(res);

    destroyPQExpBuffer(q);
    return 1;
}

static int dumpTableData_insert ( Archive fout,
void *  dcontext 
) [static]

Definition at line 1545 of file pg_dump.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralAH, archprintf(), archputs(), BITOID, BOOLOID, column_inserts, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), _tableInfo::dobj, ExecuteSqlQuery(), ExecuteSqlStatement(), _tableDataInfo::filtercond, FLOAT4OID, FLOAT8OID, fmtId(), fmtQualifiedId(), INT2OID, INT4OID, INT8OID, _dumpableObject::name, NUMERICOID, OIDOID, PGRES_TUPLES_OK, PQclear(), PQfname(), PQftype(), PQgetisnull(), PQgetvalue(), PQnfields(), PQntuples(), Archive::remoteVersion, resetPQExpBuffer(), selectSourceSchema(), _tableDataInfo::tdtable, and VARBITOID.

{
    TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
    TableInfo  *tbinfo = tdinfo->tdtable;
    const char *classname = tbinfo->dobj.name;
    PQExpBuffer q = createPQExpBuffer();
    PGresult   *res;
    int         tuple;
    int         nfields;
    int         field;

    /*
     * Make sure we are in proper schema.  We will qualify the table name
     * below anyway (in case its name conflicts with a pg_catalog table); but
     * this ensures reproducible results in case the table contains regproc,
     * regclass, etc columns.
     */
    selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);

    if (fout->remoteVersion >= 70100)
    {
        appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
                          "SELECT * FROM ONLY %s",
                          fmtQualifiedId(fout->remoteVersion,
                                         tbinfo->dobj.namespace->dobj.name,
                                         classname));
    }
    else
    {
        appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
                          "SELECT * FROM %s",
                          fmtQualifiedId(fout->remoteVersion,
                                         tbinfo->dobj.namespace->dobj.name,
                                         classname));
    }
    if (tdinfo->filtercond)
        appendPQExpBuffer(q, " %s", tdinfo->filtercond);

    ExecuteSqlStatement(fout, q->data);

    while (1)
    {
        res = ExecuteSqlQuery(fout, "FETCH 100 FROM _pg_dump_cursor",
                              PGRES_TUPLES_OK);
        nfields = PQnfields(res);
        for (tuple = 0; tuple < PQntuples(res); tuple++)
        {
            archprintf(fout, "INSERT INTO %s ", fmtId(classname));
            if (nfields == 0)
            {
                /* corner case for zero-column table */
                archprintf(fout, "DEFAULT VALUES;\n");
                continue;
            }
            if (column_inserts)
            {
                resetPQExpBuffer(q);
                appendPQExpBuffer(q, "(");
                for (field = 0; field < nfields; field++)
                {
                    if (field > 0)
                        appendPQExpBuffer(q, ", ");
                    appendPQExpBufferStr(q, fmtId(PQfname(res, field)));
                }
                appendPQExpBuffer(q, ") ");
                archputs(q->data, fout);
            }
            archprintf(fout, "VALUES (");
            for (field = 0; field < nfields; field++)
            {
                if (field > 0)
                    archprintf(fout, ", ");
                if (PQgetisnull(res, tuple, field))
                {
                    archprintf(fout, "NULL");
                    continue;
                }

                /* XXX This code is partially duplicated in ruleutils.c */
                switch (PQftype(res, field))
                {
                    case INT2OID:
                    case INT4OID:
                    case INT8OID:
                    case OIDOID:
                    case FLOAT4OID:
                    case FLOAT8OID:
                    case NUMERICOID:
                        {
                            /*
                             * These types are printed without quotes unless
                             * they contain values that aren't accepted by the
                             * scanner unquoted (e.g., 'NaN').  Note that
                             * strtod() and friends might accept NaN, so we
                             * can't use that to test.
                             *
                             * In reality we only need to defend against
                             * infinity and NaN, so we need not get too crazy
                             * about pattern matching here.
                             */
                            const char *s = PQgetvalue(res, tuple, field);

                            if (strspn(s, "0123456789 +-eE.") == strlen(s))
                                archprintf(fout, "%s", s);
                            else
                                archprintf(fout, "'%s'", s);
                        }
                        break;

                    case BITOID:
                    case VARBITOID:
                        archprintf(fout, "B'%s'",
                                   PQgetvalue(res, tuple, field));
                        break;

                    case BOOLOID:
                        if (strcmp(PQgetvalue(res, tuple, field), "t") == 0)
                            archprintf(fout, "true");
                        else
                            archprintf(fout, "false");
                        break;

                    default:
                        /* All other types are printed as string literals. */
                        resetPQExpBuffer(q);
                        appendStringLiteralAH(q,
                                              PQgetvalue(res, tuple, field),
                                              fout);
                        archputs(q->data, fout);
                        break;
                }
            }
            archprintf(fout, ");\n");
        }

        if (PQntuples(res) <= 0)
        {
            PQclear(res);
            break;
        }
        PQclear(res);
    }

    archprintf(fout, "\n\n");

    ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor");

    destroyPQExpBuffer(q);
    return 1;
}

static void dumpTableSchema ( Archive fout,
TableInfo tbinfo 
) [static]

Definition at line 12791 of file pg_dump.c.

References _attrDefInfo::adef_expr, appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), _tableInfo::attalign, _tableInfo::attcollation, _tableInfo::attfdwoptions, _tableInfo::attisdropped, _tableInfo::attislocal, _tableInfo::attlen, _tableInfo::attnames, _tableInfo::attoptions, _tableInfo::attrdefs, _tableInfo::attstattarget, _tableInfo::attstorage, _tableInfo::atttypmod, _tableInfo::atttypnames, binary_upgrade, binary_upgrade_extension_member(), binary_upgrade_set_pg_class_oids(), binary_upgrade_set_type_oids_by_rel_oid(), _dumpableObject::catId, _tableInfo::checkexprs, _constraintInfo::condef, _constraintInfo::conislocal, createPQExpBuffer(), createViewAsClause(), PQExpBufferData::data, destroyPQExpBuffer(), _constraintInfo::dobj, _collInfo::dobj, _tableInfo::dobj, _dumpableObject::dumpId, dumpTableComment(), dumpTableConstraintComment(), dumpTableSecLabel(), ExecuteSqlQueryForSingleRow(), findCollationByOid(), fmtId(), _tableInfo::frozenxid, _tableInfo::hasoids, _tableInfo::inhNotNull, myFormatType(), _dumpableObject::name, _tableInfo::ncheck, _tableInfo::notnull, NULL, _tableInfo::numatts, _tableInfo::numParents, CatalogId::oid, OidIsValid, _tableInfo::parents, pg_strdup(), PQclear(), PQfnumber(), PQgetvalue(), _tableInfo::relkind, RELKIND_FOREIGN_TABLE, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_VIEW, _tableInfo::reloftype, _tableInfo::reloptions, _tableInfo::relpersistence, RELPERSISTENCE_UNLOGGED, _tableInfo::reltablespace, Archive::remoteVersion, _tableInfo::rolname, SECTION_PRE_DATA, selectSourceSchema(), _constraintInfo::separate, _attrDefInfo::separate, shouldPrintColumn(), _tableInfo::toast_frozenxid, _tableInfo::toast_oid, _tableInfo::toast_reloptions, and _tableInfo::typstorage.

Referenced by dumpTable().

{
    PQExpBuffer q = createPQExpBuffer();
    PQExpBuffer delq = createPQExpBuffer();
    PQExpBuffer labelq = createPQExpBuffer();
    int         numParents;
    TableInfo **parents;
    int         actual_atts;    /* number of attrs in this CREATE statement */
    const char *reltypename;
    char       *storage;
    char       *srvname;
    char       *ftoptions;
    int         j,
                k;

    /* Make sure we are in proper schema */
    selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);

    if (binary_upgrade)
        binary_upgrade_set_type_oids_by_rel_oid(fout, q,
                                                tbinfo->dobj.catId.oid);

    /* Is it a table or a view? */
    if (tbinfo->relkind == RELKIND_VIEW)
    {
        PQExpBuffer result;

        reltypename = "VIEW";

        /*
         * DROP must be fully qualified in case same name appears in
         * pg_catalog
         */
        appendPQExpBuffer(delq, "DROP VIEW %s.",
                          fmtId(tbinfo->dobj.namespace->dobj.name));
        appendPQExpBuffer(delq, "%s;\n",
                          fmtId(tbinfo->dobj.name));

        if (binary_upgrade)
            binary_upgrade_set_pg_class_oids(fout, q,
                                             tbinfo->dobj.catId.oid, false);

        appendPQExpBuffer(q, "CREATE VIEW %s", fmtId(tbinfo->dobj.name));
        if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
            appendPQExpBuffer(q, " WITH (%s)", tbinfo->reloptions);
        result = createViewAsClause(fout, tbinfo);
        appendPQExpBuffer(q, " AS\n%s;\n", result->data);
        destroyPQExpBuffer(result);

        appendPQExpBuffer(labelq, "VIEW %s",
                          fmtId(tbinfo->dobj.name));
    }
    else
    {
        switch (tbinfo->relkind)
        {
            case (RELKIND_FOREIGN_TABLE):
                {
                    PQExpBuffer query = createPQExpBuffer();
                    PGresult   *res;
                    int         i_srvname;
                    int         i_ftoptions;

                    reltypename = "FOREIGN TABLE";

                    /* retrieve name of foreign server and generic options */
                    appendPQExpBuffer(query,
                                      "SELECT fs.srvname, "
                                      "pg_catalog.array_to_string(ARRAY("
                             "SELECT pg_catalog.quote_ident(option_name) || "
                             "' ' || pg_catalog.quote_literal(option_value) "
                            "FROM pg_catalog.pg_options_to_table(ftoptions) "
                                      "ORDER BY option_name"
                                      "), E',\n    ') AS ftoptions "
                                      "FROM pg_catalog.pg_foreign_table ft "
                                      "JOIN pg_catalog.pg_foreign_server fs "
                                      "ON (fs.oid = ft.ftserver) "
                                      "WHERE ft.ftrelid = '%u'",
                                      tbinfo->dobj.catId.oid);
                    res = ExecuteSqlQueryForSingleRow(fout, query->data);
                    i_srvname = PQfnumber(res, "srvname");
                    i_ftoptions = PQfnumber(res, "ftoptions");
                    srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
                    ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
                    PQclear(res);
                    destroyPQExpBuffer(query);
                    break;
                }
            case (RELKIND_MATVIEW):
                reltypename = "MATERIALIZED VIEW";
                srvname = NULL;
                ftoptions = NULL;
                break;
            default:
                reltypename = "TABLE";
                srvname = NULL;
                ftoptions = NULL;
        }

        numParents = tbinfo->numParents;
        parents = tbinfo->parents;

        /*
         * DROP must be fully qualified in case same name appears in
         * pg_catalog
         */
        appendPQExpBuffer(delq, "DROP %s %s.", reltypename,
                          fmtId(tbinfo->dobj.namespace->dobj.name));
        appendPQExpBuffer(delq, "%s;\n",
                          fmtId(tbinfo->dobj.name));

        appendPQExpBuffer(labelq, "%s %s", reltypename,
                          fmtId(tbinfo->dobj.name));

        if (binary_upgrade)
            binary_upgrade_set_pg_class_oids(fout, q,
                                             tbinfo->dobj.catId.oid, false);

        appendPQExpBuffer(q, "CREATE %s%s %s",
                          tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
                          "UNLOGGED " : "",
                          reltypename,
                          fmtId(tbinfo->dobj.name));

        /*
         * Attach to type, if reloftype; except in case of a binary upgrade,
         * we dump the table normally and attach it to the type afterward.
         */
        if (tbinfo->reloftype && !binary_upgrade)
            appendPQExpBuffer(q, " OF %s", tbinfo->reloftype);

        if (tbinfo->relkind != RELKIND_MATVIEW)
        {
            /* Dump the attributes */
            actual_atts = 0;
            for (j = 0; j < tbinfo->numatts; j++)
            {
                /*
                 * Normally, dump if it's locally defined in this table, and
                 * not dropped.  But for binary upgrade, we'll dump all the
                 * columns, and then fix up the dropped and nonlocal cases
                 * below.
                 */
                if (shouldPrintColumn(tbinfo, j))
                {
                    /*
                     * Default value --- suppress if to be printed separately.
                     */
                    bool        has_default = (tbinfo->attrdefs[j] != NULL &&
                                             !tbinfo->attrdefs[j]->separate);

                    /*
                     * Not Null constraint --- suppress if inherited, except
                     * in binary-upgrade case where that won't work.
                     */
                    bool        has_notnull = (tbinfo->notnull[j] &&
                                               (!tbinfo->inhNotNull[j] ||
                                                binary_upgrade));

                    /* Skip column if fully defined by reloftype */
                    if (tbinfo->reloftype &&
                        !has_default && !has_notnull && !binary_upgrade)
                        continue;

                    /* Format properly if not first attr */
                    if (actual_atts == 0)
                        appendPQExpBuffer(q, " (");
                    else
                        appendPQExpBuffer(q, ",");
                    appendPQExpBuffer(q, "\n    ");
                    actual_atts++;

                    /* Attribute name */
                    appendPQExpBuffer(q, "%s",
                                      fmtId(tbinfo->attnames[j]));

                    if (tbinfo->attisdropped[j])
                    {
                        /*
                         * ALTER TABLE DROP COLUMN clears
                         * pg_attribute.atttypid, so we will not have gotten a
                         * valid type name; insert INTEGER as a stopgap. We'll
                         * clean things up later.
                         */
                        appendPQExpBuffer(q, " INTEGER /* dummy */");
                        /* Skip all the rest, too */
                        continue;
                    }

                    /* Attribute type */
                    if (tbinfo->reloftype && !binary_upgrade)
                    {
                        appendPQExpBuffer(q, " WITH OPTIONS");
                    }
                    else if (fout->remoteVersion >= 70100)
                    {
                        appendPQExpBuffer(q, " %s",
                                          tbinfo->atttypnames[j]);
                    }
                    else
                    {
                        /* If no format_type, fake it */
                        appendPQExpBuffer(q, " %s",
                                          myFormatType(tbinfo->atttypnames[j],
                                                       tbinfo->atttypmod[j]));
                    }

                    /* Add collation if not default for the type */
                    if (OidIsValid(tbinfo->attcollation[j]))
                    {
                        CollInfo   *coll;

                        coll = findCollationByOid(tbinfo->attcollation[j]);
                        if (coll)
                        {
                            /* always schema-qualify, don't try to be smart */
                            appendPQExpBuffer(q, " COLLATE %s.",
                                     fmtId(coll->dobj.namespace->dobj.name));
                            appendPQExpBuffer(q, "%s",
                                              fmtId(coll->dobj.name));
                        }
                    }

                    if (has_default)
                        appendPQExpBuffer(q, " DEFAULT %s",
                                          tbinfo->attrdefs[j]->adef_expr);

                    if (has_notnull)
                        appendPQExpBuffer(q, " NOT NULL");
                }
            }

            /*
             * Add non-inherited CHECK constraints, if any.
             */
            for (j = 0; j < tbinfo->ncheck; j++)
            {
                ConstraintInfo *constr = &(tbinfo->checkexprs[j]);

                if (constr->separate || !constr->conislocal)
                    continue;

                if (actual_atts == 0)
                    appendPQExpBuffer(q, " (\n    ");
                else
                    appendPQExpBuffer(q, ",\n    ");

                appendPQExpBuffer(q, "CONSTRAINT %s ",
                                  fmtId(constr->dobj.name));
                appendPQExpBuffer(q, "%s", constr->condef);

                actual_atts++;
            }

            if (actual_atts)
                appendPQExpBuffer(q, "\n)");
            else if (!(tbinfo->reloftype && !binary_upgrade))
            {
                /*
                 * We must have a parenthesized attribute list, even though
                 * empty, when not using the OF TYPE syntax.
                 */
                appendPQExpBuffer(q, " (\n)");
            }

            if (numParents > 0 && !binary_upgrade)
            {
                appendPQExpBuffer(q, "\nINHERITS (");
                for (k = 0; k < numParents; k++)
                {
                    TableInfo  *parentRel = parents[k];

                    if (k > 0)
                        appendPQExpBuffer(q, ", ");
                    if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
                        appendPQExpBuffer(q, "%s.",
                                fmtId(parentRel->dobj.namespace->dobj.name));
                    appendPQExpBuffer(q, "%s",
                                      fmtId(parentRel->dobj.name));
                }
                appendPQExpBuffer(q, ")");
            }

            if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
                appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
        }

        if ((tbinfo->reloptions && strlen(tbinfo->reloptions) > 0) ||
          (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0))
        {
            bool        addcomma = false;

            appendPQExpBuffer(q, "\nWITH (");
            if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
            {
                addcomma = true;
                appendPQExpBuffer(q, "%s", tbinfo->reloptions);
            }
            if (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0)
            {
                appendPQExpBuffer(q, "%s%s", addcomma ? ", " : "",
                                  tbinfo->toast_reloptions);
            }
            appendPQExpBuffer(q, ")");
        }

        /* Dump generic options if any */
        if (ftoptions && ftoptions[0])
            appendPQExpBuffer(q, "\nOPTIONS (\n    %s\n)", ftoptions);

        /*
         * For materialized views, create the AS clause just like a view.
         */
        if (tbinfo->relkind == RELKIND_MATVIEW)
        {
            PQExpBuffer result;

            result = createViewAsClause(fout, tbinfo);
            appendPQExpBuffer(q, " AS\n%s\n  WITH NO DATA;\n",
                              result->data);
            destroyPQExpBuffer(result);
        }
        else
            appendPQExpBuffer(q, ";\n");

        /*
         * To create binary-compatible heap files, we have to ensure the same
         * physical column order, including dropped columns, as in the
         * original.  Therefore, we create dropped columns above and drop them
         * here, also updating their attlen/attalign values so that the
         * dropped column can be skipped properly.  (We do not bother with
         * restoring the original attbyval setting.)  Also, inheritance
         * relationships are set up by doing ALTER INHERIT rather than using
         * an INHERITS clause --- the latter would possibly mess up the column
         * order.  That also means we have to take care about setting
         * attislocal correctly, plus fix up any inherited CHECK constraints.
         * Analogously, we set up typed tables using ALTER TABLE / OF here.
         */
        if (binary_upgrade && tbinfo->relkind == RELKIND_RELATION)
        {
            for (j = 0; j < tbinfo->numatts; j++)
            {
                if (tbinfo->attisdropped[j])
                {
                    appendPQExpBuffer(q, "\n-- For binary upgrade, recreate dropped column.\n");
                    appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
                                      "SET attlen = %d, "
                                      "attalign = '%c', attbyval = false\n"
                                      "WHERE attname = ",
                                      tbinfo->attlen[j],
                                      tbinfo->attalign[j]);
                    appendStringLiteralAH(q, tbinfo->attnames[j], fout);
                    appendPQExpBuffer(q, "\n  AND attrelid = ");
                    appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
                    appendPQExpBuffer(q, "::pg_catalog.regclass;\n");

                    appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
                                      fmtId(tbinfo->dobj.name));
                    appendPQExpBuffer(q, "DROP COLUMN %s;\n",
                                      fmtId(tbinfo->attnames[j]));
                }
                else if (!tbinfo->attislocal[j])
                {
                    appendPQExpBuffer(q, "\n-- For binary upgrade, recreate inherited column.\n");
                    appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
                                      "SET attislocal = false\n"
                                      "WHERE attname = ");
                    appendStringLiteralAH(q, tbinfo->attnames[j], fout);
                    appendPQExpBuffer(q, "\n  AND attrelid = ");
                    appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
                    appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
                }
            }

            for (k = 0; k < tbinfo->ncheck; k++)
            {
                ConstraintInfo *constr = &(tbinfo->checkexprs[k]);

                if (constr->separate || constr->conislocal)
                    continue;

                appendPQExpBuffer(q, "\n-- For binary upgrade, set up inherited constraint.\n");
                appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
                                  fmtId(tbinfo->dobj.name));
                appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
                                  fmtId(constr->dobj.name));
                appendPQExpBuffer(q, "%s;\n", constr->condef);
                appendPQExpBuffer(q, "UPDATE pg_catalog.pg_constraint\n"
                                  "SET conislocal = false\n"
                                  "WHERE contype = 'c' AND conname = ");
                appendStringLiteralAH(q, constr->dobj.name, fout);
                appendPQExpBuffer(q, "\n  AND conrelid = ");
                appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
                appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
            }

            if (numParents > 0)
            {
                appendPQExpBuffer(q, "\n-- For binary upgrade, set up inheritance this way.\n");
                for (k = 0; k < numParents; k++)
                {
                    TableInfo  *parentRel = parents[k];

                    appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT ",
                                      fmtId(tbinfo->dobj.name));
                    if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
                        appendPQExpBuffer(q, "%s.",
                                fmtId(parentRel->dobj.namespace->dobj.name));
                    appendPQExpBuffer(q, "%s;\n",
                                      fmtId(parentRel->dobj.name));
                }
            }

            if (tbinfo->reloftype)
            {
                appendPQExpBuffer(q, "\n-- For binary upgrade, set up typed tables this way.\n");
                appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n",
                                  fmtId(tbinfo->dobj.name),
                                  tbinfo->reloftype);
            }

            appendPQExpBuffer(q, "\n-- For binary upgrade, set heap's relfrozenxid\n");
            appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
                              "SET relfrozenxid = '%u'\n"
                              "WHERE oid = ",
                              tbinfo->frozenxid);
            appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
            appendPQExpBuffer(q, "::pg_catalog.regclass;\n");

            if (tbinfo->toast_oid)
            {
                /* We preserve the toast oids, so we can use it during restore */
                appendPQExpBuffer(q, "\n-- For binary upgrade, set toast's relfrozenxid\n");
                appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
                                  "SET relfrozenxid = '%u'\n"
                                  "WHERE oid = '%u';\n",
                                  tbinfo->toast_frozenxid, tbinfo->toast_oid);
            }
        }

        /*
         * Dump additional per-column properties that we can't handle in the
         * main CREATE TABLE command.
         */
        for (j = 0; j < tbinfo->numatts; j++)
        {
            /* None of this applies to dropped columns */
            if (tbinfo->attisdropped[j])
                continue;

            /*
             * If we didn't dump the column definition explicitly above, and
             * it is NOT NULL and did not inherit that property from a parent,
             * we have to mark it separately.
             */
            if (!shouldPrintColumn(tbinfo, j) &&
                tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
            {
                appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
                                  fmtId(tbinfo->dobj.name));
                appendPQExpBuffer(q, "ALTER COLUMN %s SET NOT NULL;\n",
                                  fmtId(tbinfo->attnames[j]));
            }

            /*
             * Dump per-column statistics information. We only issue an ALTER
             * TABLE statement if the attstattarget entry for this column is
             * non-negative (i.e. it's not the default value)
             */
            if (tbinfo->attstattarget[j] >= 0)
            {
                appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
                                  fmtId(tbinfo->dobj.name));
                appendPQExpBuffer(q, "ALTER COLUMN %s ",
                                  fmtId(tbinfo->attnames[j]));
                appendPQExpBuffer(q, "SET STATISTICS %d;\n",
                                  tbinfo->attstattarget[j]);
            }

            /*
             * Dump per-column storage information.  The statement is only
             * dumped if the storage has been changed from the type's default.
             */
            if (tbinfo->attstorage[j] != tbinfo->typstorage[j])
            {
                switch (tbinfo->attstorage[j])
                {
                    case 'p':
                        storage = "PLAIN";
                        break;
                    case 'e':
                        storage = "EXTERNAL";
                        break;
                    case 'm':
                        storage = "MAIN";
                        break;
                    case 'x':
                        storage = "EXTENDED";
                        break;
                    default:
                        storage = NULL;
                }

                /*
                 * Only dump the statement if it's a storage type we recognize
                 */
                if (storage != NULL)
                {
                    appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
                                      fmtId(tbinfo->dobj.name));
                    appendPQExpBuffer(q, "ALTER COLUMN %s ",
                                      fmtId(tbinfo->attnames[j]));
                    appendPQExpBuffer(q, "SET STORAGE %s;\n",
                                      storage);
                }
            }

            /*
             * Dump per-column attributes.
             */
            if (tbinfo->attoptions[j] && tbinfo->attoptions[j][0] != '\0')
            {
                appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
                                  fmtId(tbinfo->dobj.name));
                appendPQExpBuffer(q, "ALTER COLUMN %s ",
                                  fmtId(tbinfo->attnames[j]));
                appendPQExpBuffer(q, "SET (%s);\n",
                                  tbinfo->attoptions[j]);
            }

            /*
             * Dump per-column fdw options.
             */
            if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
                tbinfo->attfdwoptions[j] &&
                tbinfo->attfdwoptions[j][0] != '\0')
            {
                appendPQExpBuffer(q, "ALTER FOREIGN TABLE %s ",
                                  fmtId(tbinfo->dobj.name));
                appendPQExpBuffer(q, "ALTER COLUMN %s ",
                                  fmtId(tbinfo->attnames[j]));
                appendPQExpBuffer(q, "OPTIONS (\n    %s\n);\n",
                                  tbinfo->attfdwoptions[j]);
            }
        }
    }

    if (binary_upgrade)
        binary_upgrade_extension_member(q, &tbinfo->dobj, labelq->data);

    ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
                 tbinfo->dobj.name,
                 tbinfo->dobj.namespace->dobj.name,
            (tbinfo->relkind == RELKIND_VIEW) ? NULL : tbinfo->reltablespace,
                 tbinfo->rolname,
               (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false,
                 reltypename, SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
                 NULL, 0,
                 NULL, NULL);


    /* Dump Table Comments */
    dumpTableComment(fout, tbinfo, reltypename);

    /* Dump Table Security Labels */
    dumpTableSecLabel(fout, tbinfo, reltypename);

    /* Dump comments on inlined table constraints */
    for (j = 0; j < tbinfo->ncheck; j++)
    {
        ConstraintInfo *constr = &(tbinfo->checkexprs[j]);

        if (constr->separate || !constr->conislocal)
            continue;

        dumpTableConstraintComment(fout, constr);
    }

    destroyPQExpBuffer(q);
    destroyPQExpBuffer(delq);
    destroyPQExpBuffer(labelq);
}

static void dumpTableSecLabel ( Archive fout,
TableInfo tbinfo,
const char *  reltypename 
) [static]

Definition at line 12443 of file pg_dump.c.

References appendPQExpBuffer(), appendStringLiteralAH, ArchiveEntry(), _dumpableObject::catId, createDumpId(), createPQExpBuffer(), PQExpBufferData::data, dataOnly, destroyPQExpBuffer(), _tableInfo::dobj, _dumpableObject::dumpId, findSecLabels(), fmtId(), getAttrName(), i, SecLabelItem::label, label, PQExpBufferData::len, _dumpableObject::name, no_security_labels, NULL, SecLabelItem::objsubid, CatalogId::oid, SecLabelItem::provider, resetPQExpBuffer(), _tableInfo::rolname, SECTION_NONE, and CatalogId::tableoid.

Referenced by dumpTableSchema().

{
    SecLabelItem *labels;
    int         nlabels;
    int         i;
    PQExpBuffer query;
    PQExpBuffer target;

    /* do nothing, if --no-security-labels is supplied */
    if (no_security_labels)
        return;

    /* SecLabel are SCHEMA not data */
    if (dataOnly)
        return;

    /* Search for comments associated with relation, using table */
    nlabels = findSecLabels(fout,
                            tbinfo->dobj.catId.tableoid,
                            tbinfo->dobj.catId.oid,
                            &labels);

    /* If security labels exist, build SECURITY LABEL statements */
    if (nlabels <= 0)
        return;

    query = createPQExpBuffer();
    target = createPQExpBuffer();

    for (i = 0; i < nlabels; i++)
    {
        const char *colname;
        const char *provider = labels[i].provider;
        const char *label = labels[i].label;
        int         objsubid = labels[i].objsubid;

        resetPQExpBuffer(target);
        if (objsubid == 0)
        {
            appendPQExpBuffer(target, "%s %s", reltypename,
                              fmtId(tbinfo->dobj.name));
        }
        else
        {
            colname = getAttrName(objsubid, tbinfo);
            /* first fmtId result must be consumed before calling it again */
            appendPQExpBuffer(target, "COLUMN %s", fmtId(tbinfo->dobj.name));
            appendPQExpBuffer(target, ".%s", fmtId(colname));
        }
        appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
                          fmtId(provider), target->data);
        appendStringLiteralAH(query, label, fout);
        appendPQExpBuffer(query, ";\n");
    }
    if (query->len > 0)
    {
        resetPQExpBuffer(target);
        appendPQExpBuffer(target, "%s %s", reltypename,
                          fmtId(tbinfo->dobj.name));
        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                     target->data,
                     tbinfo->dobj.namespace->dobj.name,
                     NULL, tbinfo->rolname,
                     false, "SECURITY LABEL", SECTION_NONE,
                     query->data, "", NULL,
                     &(tbinfo->dobj.dumpId), 1,
                     NULL, NULL);
    }
    destroyPQExpBuffer(query);
    destroyPQExpBuffer(target);
}

static void dumpTrigger ( Archive fout,
TriggerInfo tginfo 
) [static]