src/bin/pg_dump/pg_dump.c
static void
dumpTable(Archive *fout, const TableInfo *tbinfo)
{
	DumpOptions *dopt = fout->dopt;
	DumpId		tableAclDumpId = InvalidDumpId;
	char	   *namecopy;

	/* Do nothing in data-only dump */
	if (dopt->dataOnly)
		return;

	if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
	{
		if (tbinfo->relkind == RELKIND_SEQUENCE)
			dumpSequence(fout, tbinfo);
		else
			dumpTableSchema(fout, tbinfo);
	}

	/* Handle the ACL here */
	namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
	if (tbinfo->dobj.dump & DUMP_COMPONENT_ACL)
	{
		const char *objtype =
		(tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";

		tableAclDumpId =
			dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
					objtype, namecopy, NULL,
					tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
					&tbinfo->dacl);
	}

	/*
	 * 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.  Doing it this way also allows us to dump
	 * ACLs for catalogs that we didn't mark "interesting" back in getTables.
	 */
	if ((tbinfo->dobj.dump & DUMP_COMPONENT_ACL) && tbinfo->hascolumnACLs)
	{
		PQExpBuffer query = createPQExpBuffer();
		PGresult   *res;
		int			i;

		if (!fout->is_prepared[PREPQUERY_GETCOLUMNACLS])
		{
			/* Set up query for column ACLs */
			appendPQExpBufferStr(query,
								 "PREPARE getColumnACLs(pg_catalog.oid) AS\n");

			if (fout->remoteVersion >= 90600)
			{
				/*
				 * In principle we should call acldefault('c', relowner) to
				 * get the default ACL for a column.  However, we don't
				 * currently store the numeric OID of the relowner in
				 * TableInfo.  We could convert the owner name using regrole,
				 * but that creates a risk of failure due to concurrent role
				 * renames.  Given that the default ACL for columns is empty
				 * and is likely to stay that way, it's not worth extra cycles
				 * and risk to avoid hard-wiring that knowledge here.
				 */
				appendPQExpBufferStr(query,
									 "SELECT at.attname, "
									 "at.attacl, "
									 "'{}' AS acldefault, "
									 "pip.privtype, pip.initprivs "
									 "FROM pg_catalog.pg_attribute at "
									 "LEFT JOIN pg_catalog.pg_init_privs pip ON "
									 "(at.attrelid = pip.objoid "
									 "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass "
									 "AND at.attnum = pip.objsubid) "
									 "WHERE at.attrelid = $1 AND "
									 "NOT at.attisdropped "
									 "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) "
									 "ORDER BY at.attnum");
			}
			else
			{
				appendPQExpBufferStr(query,
									 "SELECT attname, attacl, '{}' AS acldefault, "
									 "NULL AS privtype, NULL AS initprivs "
									 "FROM pg_catalog.pg_attribute "
									 "WHERE attrelid = $1 AND NOT attisdropped "
									 "AND attacl IS NOT NULL "
									 "ORDER BY attnum");
			}

			ExecuteSqlStatement(fout, query->data);

			fout->is_prepared[PREPQUERY_GETCOLUMNACLS] = true;
		}

		printfPQExpBuffer(query,
						  "EXECUTE getColumnACLs('%u')",
						  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	   *acldefault = PQgetvalue(res, i, 2);
			char		privtype = *(PQgetvalue(res, i, 3));
			char	   *initprivs = PQgetvalue(res, i, 4);
			DumpableAcl coldacl;
			char	   *attnamecopy;

			coldacl.acl = attacl;
			coldacl.acldefault = acldefault;
			coldacl.privtype = privtype;
			coldacl.initprivs = initprivs;
			attnamecopy = pg_strdup(fmtId(attname));

			/*
			 * Column's GRANT type is always TABLE.  Each column ACL depends
			 * on the table-level ACL, since we can restore column ACLs in
			 * parallel but the table-level ACL has to be done first.
			 */
			dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
					"TABLE", namecopy, attnamecopy,
					tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
					&coldacl);
			free(attnamecopy);
		}
		PQclear(res);
		destroyPQExpBuffer(query);
	}

	free(namecopy);
}
/*
 * dumpTable
 *	  write out to fout the declarations (not data) of a user-defined table
 */
dumpTable
write out to fout the declarations (not data) of a user-defined table
dumpTable write out to fout the declarations ( not data ) of a user - defined table
static void
dumpTable(Archive *fout, const TableInfo *tbinfo)
{
	DumpOptions *dopt = fout->dopt;
	DumpId		tableAclDumpId = InvalidDumpId;
	char	   *namecopy;
	if (dopt->dataOnly)
		return;
	if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
	{
		if (tbinfo->relkind == RELKIND_SEQUENCE)
			dumpSequence(fout, tbinfo);
		else
			dumpTableSchema(fout, tbinfo);
	}
	namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
	if (tbinfo->dobj.dump & DUMP_COMPONENT_ACL)
	{
		const char *objtype =
		(tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
		tableAclDumpId =
			dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
					objtype, namecopy, NULL,
					tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
					&tbinfo->dacl);
	}
	if ((tbinfo->dobj.dump & DUMP_COMPONENT_ACL) && tbinfo->hascolumnACLs)
	{
		PQExpBuffer query = createPQExpBuffer();
		PGresult   *res;
		int			i;
		if (!fout->is_prepared[PREPQUERY_GETCOLUMNACLS])
		{
			appendPQExpBufferStr(query,
								 "PREPARE getColumnACLs(pg_catalog.oid) AS\n");
			if (fout->remoteVersion >= 90600)
			{
				appendPQExpBufferStr(query,
									 "SELECT at.attname, "
									 "at.attacl, "
									 "'{}' AS acldefault, "
									 "pip.privtype, pip.initprivs "
									 "FROM pg_catalog.pg_attribute at "
									 "LEFT JOIN pg_catalog.pg_init_privs pip ON "
									 "(at.attrelid = pip.objoid "
									 "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass "
									 "AND at.attnum = pip.objsubid) "
									 "WHERE at.attrelid = $1 AND "
									 "NOT at.attisdropped "
									 "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) "
									 "ORDER BY at.attnum");
			}
			else
			{
				appendPQExpBufferStr(query,
									 "SELECT attname, attacl, '{}' AS acldefault, "
									 "NULL AS privtype, NULL AS initprivs "
									 "FROM pg_catalog.pg_attribute "
									 "WHERE attrelid = $1 AND NOT attisdropped "
									 "AND attacl IS NOT NULL "
									 "ORDER BY attnum");
			}
			ExecuteSqlStatement(fout, query->data);
			fout->is_prepared[PREPQUERY_GETCOLUMNACLS] = true;
		}
		printfPQExpBuffer(query,
						  "EXECUTE getColumnACLs('%u')",
						  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	   *acldefault = PQgetvalue(res, i, 2);
			char		privtype = *(PQgetvalue(res, i, 3));
			char	   *initprivs = PQgetvalue(res, i, 4);
			DumpableAcl coldacl;
			char	   *attnamecopy;
			coldacl.acl = attacl;
			coldacl.acldefault = acldefault;
			coldacl.privtype = privtype;
			coldacl.initprivs = initprivs;
			attnamecopy = pg_strdup(fmtId(attname));
			dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
					"TABLE", namecopy, attnamecopy,
					tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
					&coldacl);
			free(attnamecopy);
		}
		PQclear(res);
		destroyPQExpBuffer(query);
	}
	free(namecopy);
}
static void dumpTable ( Archive * fout , const TableInfo * tbinfo ) { DumpOptions * dopt = fout -> dopt ; DumpId tableAclDumpId = InvalidDumpId ; char * namecopy ; if ( dopt -> dataOnly ) return ; if ( tbinfo -> dobj . dump & DUMP_COMPONENT_DEFINITION ) { if ( tbinfo -> relkind == RELKIND_SEQUENCE ) dumpSequence ( fout , tbinfo ) ; else dumpTableSchema ( fout , tbinfo ) ; } namecopy = pg_strdup ( fmtId ( tbinfo -> dobj . name ) ) ; if ( tbinfo -> dobj . dump & DUMP_COMPONENT_ACL ) { const char * objtype = ( tbinfo -> relkind == RELKIND_SEQUENCE ) ? " " : " " ; tableAclDumpId = dumpACL ( fout , tbinfo -> dobj . dumpId , InvalidDumpId , objtype , namecopy , NULL , tbinfo -> dobj . namespace -> dobj . name , tbinfo -> rolname , & tbinfo -> dacl ) ; } if ( ( tbinfo -> dobj . dump & DUMP_COMPONENT_ACL ) && tbinfo -> hascolumnACLs ) { PQExpBuffer query = createPQExpBuffer ( ) ; PGresult * res ; int i ; if ( ! fout -> is_prepared [ PREPQUERY_GETCOLUMNACLS ] ) { appendPQExpBufferStr ( query , " \n " ) ; if ( fout -> remoteVersion >= 90600 ) { appendPQExpBufferStr ( query , " " " " " " " " " " " " " " " " " " " " " " " " " " ) ; } else { appendPQExpBufferStr ( query , " " " " " " " " " " " " ) ; } ExecuteSqlStatement ( fout , query -> data ) ; fout -> is_prepared [ PREPQUERY_GETCOLUMNACLS ] = true ; } printfPQExpBuffer ( query , " " , 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 * acldefault = PQgetvalue ( res , i , 2 ) ; char privtype = * ( PQgetvalue ( res , i , 3 ) ) ; char * initprivs = PQgetvalue ( res , i , 4 ) ; DumpableAcl coldacl ; char * attnamecopy ; coldacl . acl = attacl ; coldacl . acldefault = acldefault ; coldacl . privtype = privtype ; coldacl . initprivs = initprivs ; attnamecopy = pg_strdup ( fmtId ( attname ) ) ; dumpACL ( fout , tbinfo -> dobj . dumpId , tableAclDumpId , " " , namecopy , attnamecopy , tbinfo -> dobj . namespace -> dobj . name , tbinfo -> rolname , & coldacl ) ; free ( attnamecopy ) ; } PQclear ( res ) ; destroyPQExpBuffer ( query ) ; } free ( namecopy ) ; }
dumpTable
        write out to fout the declarations (not data) of a user-defined table
dumpTable write out to fout the declarations ( not data ) of a user - defined table
/* Do nothing in data-only dump */ /* Handle the ACL here */ /*
	 * 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.  Doing it this way also allows us to dump
	 * ACLs for catalogs that we didn't mark "interesting" back in getTables.
	 */ /* Set up query for column ACLs */ /*
				 * In principle we should call acldefault('c', relowner) to
				 * get the default ACL for a column.  However, we don't
				 * currently store the numeric OID of the relowner in
				 * TableInfo.  We could convert the owner name using regrole,
				 * but that creates a risk of failure due to concurrent role
				 * renames.  Given that the default ACL for columns is empty
				 * and is likely to stay that way, it's not worth extra cycles
				 * and risk to avoid hard-wiring that knowledge here.
				 */ /*
			 * Column's GRANT type is always TABLE.  Each column ACL depends
			 * on the table-level ACL, since we can restore column ACLs in
			 * parallel but the table-level ACL has to be done first.
			 */