Header And Logo

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

Data Structures | Typedefs | Functions | Variables

dumputils.h File Reference

#include "libpq-fe.h"
#include "pqexpbuffer.h"
Include dependency graph for dumputils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  SimpleStringListCell
struct  SimpleStringList

Typedefs

typedef struct SimpleStringListCell SimpleStringListCell
typedef struct SimpleStringList SimpleStringList

Functions

const char * fmtId (const char *identifier)
const char * fmtQualifiedId (int remoteVersion, const char *schema, const char *id)
void appendStringLiteral (PQExpBuffer buf, const char *str, int encoding, bool std_strings)
void appendStringLiteralConn (PQExpBuffer buf, const char *str, PGconn *conn)
void appendStringLiteralDQ (PQExpBuffer buf, const char *str, const char *dqprefix)
void appendByteaLiteral (PQExpBuffer buf, const unsigned char *str, size_t length, bool std_strings)
bool parsePGArray (const char *atext, char ***itemarray, int *nitems)
bool buildACLCommands (const char *name, const char *subname, const char *type, const char *acls, const char *owner, const char *prefix, int remoteVersion, PQExpBuffer sql)
bool buildDefaultACLCommands (const char *type, const char *nspname, const char *acls, const char *owner, int remoteVersion, PQExpBuffer sql)
bool processSQLNamePattern (PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
void buildShSecLabelQuery (PGconn *conn, const char *catalog_name, uint32 objectId, PQExpBuffer sql)
void emitShSecLabels (PGconn *conn, PGresult *res, PQExpBuffer buffer, const char *target, const char *objname)
void set_dump_section (const char *arg, int *dumpSections)
void simple_string_list_append (SimpleStringList *list, const char *val)
bool simple_string_list_member (SimpleStringList *list, const char *val)

Variables

int quote_all_identifiers
PQExpBuffer(* getLocalPQExpBuffer )(void)

Typedef Documentation


Function Documentation

void appendByteaLiteral ( PQExpBuffer  buf,
const unsigned char *  str,
size_t  length,
bool  std_strings 
)

Definition at line 351 of file dumputils.c.

References PQExpBufferData::data, enlargePQExpBuffer(), hextbl, and PQExpBufferData::len.

{
    const unsigned char *source = str;
    char       *target;

    static const char hextbl[] = "0123456789abcdef";

    /*
     * This implementation is hard-wired to produce hex-format output. We do
     * not know the server version the output will be loaded into, so making
     * an intelligent format choice is impossible.  It might be better to
     * always use the old escaped format.
     */
    if (!enlargePQExpBuffer(buf, 2 * length + 5))
        return;

    target = buf->data + buf->len;
    *target++ = '\'';
    if (!std_strings)
        *target++ = '\\';
    *target++ = '\\';
    *target++ = 'x';

    while (length-- > 0)
    {
        unsigned char c = *source++;

        *target++ = hextbl[(c >> 4) & 0xF];
        *target++ = hextbl[c & 0xF];
    }

    /* Write the terminating quote and NUL character. */
    *target++ = '\'';
    *target = '\0';

    buf->len = target - buf->data;
}

void appendStringLiteral ( PQExpBuffer  buf,
const char *  str,
int  encoding,
bool  std_strings 
)

Definition at line 192 of file dumputils.c.

References PQExpBufferData::data, enlargePQExpBuffer(), i, IS_HIGHBIT_SET, PQExpBufferData::len, length(), PQExpBufferData::maxlen, PQmblen(), and SQL_STR_DOUBLE.

Referenced by appendStringLiteralConn().

{
    size_t      length = strlen(str);
    const char *source = str;
    char       *target;

    if (!enlargePQExpBuffer(buf, 2 * length + 2))
        return;

    target = buf->data + buf->len;
    *target++ = '\'';

    while (*source != '\0')
    {
        char        c = *source;
        int         len;
        int         i;

        /* Fast path for plain ASCII */
        if (!IS_HIGHBIT_SET(c))
        {
            /* Apply quoting if needed */
            if (SQL_STR_DOUBLE(c, !std_strings))
                *target++ = c;
            /* Copy the character */
            *target++ = c;
            source++;
            continue;
        }

        /* Slow path for possible multibyte characters */
        len = PQmblen(source, encoding);

        /* Copy the character */
        for (i = 0; i < len; i++)
        {
            if (*source == '\0')
                break;
            *target++ = *source++;
        }

        /*
         * If we hit premature end of string (ie, incomplete multibyte
         * character), try to pad out to the correct length with spaces. We
         * may not be able to pad completely, but we will always be able to
         * insert at least one pad space (since we'd not have quoted a
         * multibyte character).  This should be enough to make a string that
         * the server will error out on.
         */
        if (i < len)
        {
            char       *stop = buf->data + buf->maxlen - 2;

            for (; i < len; i++)
            {
                if (target >= stop)
                    break;
                *target++ = ' ';
            }
            break;
        }
    }

    /* Write the terminating quote and NUL character. */
    *target++ = '\'';
    *target = '\0';

    buf->len = target - buf->data;
}

void appendStringLiteralConn ( PQExpBuffer  buf,
const char *  str,
PGconn conn 
)

Definition at line 270 of file dumputils.c.

References appendPQExpBufferChar(), appendStringLiteral(), PQExpBufferData::data, enlargePQExpBuffer(), ESCAPE_STRING_SYNTAX, PQExpBufferData::len, length(), NULL, PQclientEncoding(), PQescapeStringConn(), and PQserverVersion().

Referenced by dumpCreateDB(), dumpDatabaseConfig(), dumpRoles(), dumpTablespaces(), dumpUserConfig(), emitShSecLabels(), exec_command(), getTables(), lookup_function_oid(), main(), makeAlterConfigCommand(), processSQLNamePattern(), and setup_connection().

{
    size_t      length = strlen(str);

    /*
     * XXX This is a kluge to silence escape_string_warning in our utility
     * programs.  It should go away someday.
     */
    if (strchr(str, '\\') != NULL && PQserverVersion(conn) >= 80100)
    {
        /* ensure we are not adjacent to an identifier */
        if (buf->len > 0 && buf->data[buf->len - 1] != ' ')
            appendPQExpBufferChar(buf, ' ');
        appendPQExpBufferChar(buf, ESCAPE_STRING_SYNTAX);
        appendStringLiteral(buf, str, PQclientEncoding(conn), false);
        return;
    }
    /* XXX end kluge */

    if (!enlargePQExpBuffer(buf, 2 * length + 2))
        return;
    appendPQExpBufferChar(buf, '\'');
    buf->len += PQescapeStringConn(conn, buf->data + buf->len,
                                   str, length, NULL);
    appendPQExpBufferChar(buf, '\'');
}

void appendStringLiteralDQ ( PQExpBuffer  buf,
const char *  str,
const char *  dqprefix 
)

Definition at line 308 of file dumputils.c.

References appendPQExpBufferChar(), appendPQExpBufferStr(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), and NULL.

Referenced by dumpFunc().

{
    static const char suffixes[] = "_XXXXXXX";
    int         nextchar = 0;
    PQExpBuffer delimBuf = createPQExpBuffer();

    /* start with $ + dqprefix if not NULL */
    appendPQExpBufferChar(delimBuf, '$');
    if (dqprefix)
        appendPQExpBufferStr(delimBuf, dqprefix);

    /*
     * Make sure we choose a delimiter which (without the trailing $) is not
     * present in the string being quoted. We don't check with the trailing $
     * because a string ending in $foo must not be quoted with $foo$.
     */
    while (strstr(str, delimBuf->data) != NULL)
    {
        appendPQExpBufferChar(delimBuf, suffixes[nextchar++]);
        nextchar %= sizeof(suffixes) - 1;
    }

    /* add trailing $ */
    appendPQExpBufferChar(delimBuf, '$');

    /* quote it and we are all done */
    appendPQExpBufferStr(buf, delimBuf->data);
    appendPQExpBufferStr(buf, str);
    appendPQExpBufferStr(buf, delimBuf->data);

    destroyPQExpBuffer(delimBuf);
}

bool buildACLCommands ( const char *  name,
const char *  subname,
const char *  type,
const char *  acls,
const char *  owner,
const char *  prefix,
int  remoteVersion,
PQExpBuffer  sql 
)

Definition at line 498 of file dumputils.c.

References appendPQExpBuffer(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), fmtId(), free, i, PQExpBufferData::len, parseAclItem(), parsePGArray(), printfPQExpBuffer(), and supports_grant_options.

Referenced by buildDefaultACLCommands(), dumpACL(), dumpCreateDB(), and dumpTablespaces().

{
    char      **aclitems;
    int         naclitems;
    int         i;
    PQExpBuffer grantee,
                grantor,
                privs,
                privswgo;
    PQExpBuffer firstsql,
                secondsql;
    bool        found_owner_privs = false;

    if (strlen(acls) == 0)
        return true;            /* object has default permissions */

    /* treat empty-string owner same as NULL */
    if (owner && *owner == '\0')
        owner = NULL;

    if (!parsePGArray(acls, &aclitems, &naclitems))
    {
        if (aclitems)
            free(aclitems);
        return false;
    }

    grantee = createPQExpBuffer();
    grantor = createPQExpBuffer();
    privs = createPQExpBuffer();
    privswgo = createPQExpBuffer();

    /*
     * At the end, these two will be pasted together to form the result. But
     * the owner privileges need to go before the other ones to keep the
     * dependencies valid.  In recent versions this is normally the case, but
     * in old versions they come after the PUBLIC privileges and that results
     * in problems if we need to run REVOKE on the owner privileges.
     */
    firstsql = createPQExpBuffer();
    secondsql = createPQExpBuffer();

    /*
     * Always start with REVOKE ALL FROM PUBLIC, so that we don't have to
     * wire-in knowledge about the default public privileges for different
     * kinds of objects.
     */
    appendPQExpBuffer(firstsql, "%sREVOKE ALL", prefix);
    if (subname)
        appendPQExpBuffer(firstsql, "(%s)", subname);
    appendPQExpBuffer(firstsql, " ON %s %s FROM PUBLIC;\n", type, name);

    /*
     * We still need some hacking though to cover the case where new default
     * public privileges are added in new versions: the REVOKE ALL will revoke
     * them, leading to behavior different from what the old version had,
     * which is generally not what's wanted.  So add back default privs if the
     * source database is too old to have had that particular priv.
     */
    if (remoteVersion < 80200 && strcmp(type, "DATABASE") == 0)
    {
        /* database CONNECT priv didn't exist before 8.2 */
        appendPQExpBuffer(firstsql, "%sGRANT CONNECT ON %s %s TO PUBLIC;\n",
                          prefix, type, name);
    }

    /* Scan individual ACL items */
    for (i = 0; i < naclitems; i++)
    {
        if (!parseAclItem(aclitems[i], type, name, subname, remoteVersion,
                          grantee, grantor, privs, privswgo))
        {
            free(aclitems);
            return false;
        }

        if (grantor->len == 0 && owner)
            printfPQExpBuffer(grantor, "%s", owner);

        if (privs->len > 0 || privswgo->len > 0)
        {
            if (owner
                && strcmp(grantee->data, owner) == 0
                && strcmp(grantor->data, owner) == 0)
            {
                found_owner_privs = true;

                /*
                 * For the owner, the default privilege level is ALL WITH
                 * GRANT OPTION (only ALL prior to 7.4).
                 */
                if (supports_grant_options(remoteVersion)
                    ? strcmp(privswgo->data, "ALL") != 0
                    : strcmp(privs->data, "ALL") != 0)
                {
                    appendPQExpBuffer(firstsql, "%sREVOKE ALL", prefix);
                    if (subname)
                        appendPQExpBuffer(firstsql, "(%s)", subname);
                    appendPQExpBuffer(firstsql, " ON %s %s FROM %s;\n",
                                      type, name, fmtId(grantee->data));
                    if (privs->len > 0)
                        appendPQExpBuffer(firstsql,
                                          "%sGRANT %s ON %s %s TO %s;\n",
                                          prefix, privs->data, type, name,
                                          fmtId(grantee->data));
                    if (privswgo->len > 0)
                        appendPQExpBuffer(firstsql,
                            "%sGRANT %s ON %s %s TO %s WITH GRANT OPTION;\n",
                                          prefix, privswgo->data, type, name,
                                          fmtId(grantee->data));
                }
            }
            else
            {
                /*
                 * Otherwise can assume we are starting from no privs.
                 */
                if (grantor->len > 0
                    && (!owner || strcmp(owner, grantor->data) != 0))
                    appendPQExpBuffer(secondsql, "SET SESSION AUTHORIZATION %s;\n",
                                      fmtId(grantor->data));

                if (privs->len > 0)
                {
                    appendPQExpBuffer(secondsql, "%sGRANT %s ON %s %s TO ",
                                      prefix, privs->data, type, name);
                    if (grantee->len == 0)
                        appendPQExpBuffer(secondsql, "PUBLIC;\n");
                    else if (strncmp(grantee->data, "group ",
                                     strlen("group ")) == 0)
                        appendPQExpBuffer(secondsql, "GROUP %s;\n",
                                    fmtId(grantee->data + strlen("group ")));
                    else
                        appendPQExpBuffer(secondsql, "%s;\n", fmtId(grantee->data));
                }
                if (privswgo->len > 0)
                {
                    appendPQExpBuffer(secondsql, "%sGRANT %s ON %s %s TO ",
                                      prefix, privswgo->data, type, name);
                    if (grantee->len == 0)
                        appendPQExpBuffer(secondsql, "PUBLIC");
                    else if (strncmp(grantee->data, "group ",
                                     strlen("group ")) == 0)
                        appendPQExpBuffer(secondsql, "GROUP %s",
                                    fmtId(grantee->data + strlen("group ")));
                    else
                        appendPQExpBuffer(secondsql, "%s", fmtId(grantee->data));
                    appendPQExpBuffer(secondsql, " WITH GRANT OPTION;\n");
                }

                if (grantor->len > 0
                    && (!owner || strcmp(owner, grantor->data) != 0))
                    appendPQExpBuffer(secondsql, "RESET SESSION AUTHORIZATION;\n");
            }
        }
    }

    /*
     * If we didn't find any owner privs, the owner must have revoked 'em all
     */
    if (!found_owner_privs && owner)
    {
        appendPQExpBuffer(firstsql, "%sREVOKE ALL", prefix);
        if (subname)
            appendPQExpBuffer(firstsql, "(%s)", subname);
        appendPQExpBuffer(firstsql, " ON %s %s FROM %s;\n",
                          type, name, fmtId(owner));
    }

    destroyPQExpBuffer(grantee);
    destroyPQExpBuffer(grantor);
    destroyPQExpBuffer(privs);
    destroyPQExpBuffer(privswgo);

    appendPQExpBuffer(sql, "%s%s", firstsql->data, secondsql->data);
    destroyPQExpBuffer(firstsql);
    destroyPQExpBuffer(secondsql);

    free(aclitems);

    return true;
}

bool buildDefaultACLCommands ( const char *  type,
const char *  nspname,
const char *  acls,
const char *  owner,
int  remoteVersion,
PQExpBuffer  sql 
)

Definition at line 697 of file dumputils.c.

References appendPQExpBuffer(), buildACLCommands(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), fmtId(), and NULL.

Referenced by dumpDefaultACL().

{
    bool        result;
    PQExpBuffer prefix;

    prefix = createPQExpBuffer();

    /*
     * We incorporate the target role directly into the command, rather than
     * playing around with SET ROLE or anything like that.  This is so that a
     * permissions error leads to nothing happening, rather than changing
     * default privileges for the wrong user.
     */
    appendPQExpBuffer(prefix, "ALTER DEFAULT PRIVILEGES FOR ROLE %s ",
                      fmtId(owner));
    if (nspname)
        appendPQExpBuffer(prefix, "IN SCHEMA %s ", fmtId(nspname));

    result = buildACLCommands("", NULL,
                              type, acls, owner,
                              prefix->data, remoteVersion,
                              sql);

    destroyPQExpBuffer(prefix);

    return result;
}

void buildShSecLabelQuery ( PGconn conn,
const char *  catalog_name,
uint32  objectId,
PQExpBuffer  sql 
)

Definition at line 1174 of file dumputils.c.

References appendPQExpBuffer().

Referenced by buildShSecLabels(), and dumpDatabase().

{
    appendPQExpBuffer(sql,
                      "SELECT provider, label FROM pg_catalog.pg_shseclabel "
                      "WHERE classoid = '%s'::pg_catalog.regclass AND "
                      "objoid = %u", catalog_name, objectId);
}

void emitShSecLabels ( PGconn conn,
PGresult res,
PQExpBuffer  buffer,
const char *  target,
const char *  objname 
)

Definition at line 1190 of file dumputils.c.

References appendPQExpBuffer(), appendStringLiteralConn(), fmtId(), i, label, PQgetvalue(), and PQntuples().

Referenced by buildShSecLabels(), and dumpDatabase().

{
    int         i;

    for (i = 0; i < PQntuples(res); i++)
    {
        char       *provider = PQgetvalue(res, i, 0);
        char       *label = PQgetvalue(res, i, 1);

        /* must use fmtId result before calling it again */
        appendPQExpBuffer(buffer,
                          "SECURITY LABEL FOR %s ON %s",
                          fmtId(provider), target);
        appendPQExpBuffer(buffer,
                          " %s IS ",
                          fmtId(objname));
        appendStringLiteralConn(buffer, label, conn);
        appendPQExpBuffer(buffer, ";\n");
    }
}

const char* fmtId ( const char *  identifier  ) 

Definition at line 77 of file dumputils.c.

References appendPQExpBufferChar(), appendPQExpBufferStr(), ScanKeyword::category, PQExpBufferData::data, getLocalPQExpBuffer, NULL, NumFEScanKeywords, quote_all_identifiers, ScanKeywordLookup(), and UNRESERVED_KEYWORD.

Referenced by _disableTriggersIfNecessary(), _doSetFixedOutputState(), _enableTriggersIfNecessary(), _getObjectDescription(), _printTocEntry(), _reconnectToDB(), _selectOutputSchema(), _selectTablespace(), binary_upgrade_extension_member(), buildACLCommands(), buildDefaultACLCommands(), convertRegProcReference(), describeOneTableDetails(), dropDBs(), dropRoles(), dropTablespaces(), dumpAgg(), dumpAttrDef(), dumpBaseType(), dumpCast(), dumpCollation(), dumpCompositeType(), dumpCompositeTypeColComments(), dumpConstraint(), dumpConversion(), dumpCreateDB(), dumpDatabase(), dumpDatabases(), dumpDomain(), dumpEnumType(), dumpEventTrigger(), dumpExtension(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpGroups(), dumpIndex(), dumpNamespace(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpProcLang(), dumpRangeType(), dumpRoleMembership(), dumpRoles(), dumpRule(), dumpSecLabel(), dumpSequence(), dumpSequenceData(), dumpShellType(), dumpTable(), dumpTableComment(), dumpTableConstraintComment(), dumpTableData(), dumpTableData_insert(), dumpTableSchema(), dumpTableSecLabel(), dumpTablespaces(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), dumpUserMappings(), emitShSecLabels(), exec_command(), fmtCopyColumnList(), fmtQualifiedId(), format_aggregate_signature(), format_function_arguments(), format_function_arguments_old(), format_function_signature(), getFormattedTypeName(), main(), makeAlterConfigCommand(), myFormatType(), refreshMatViewData(), reindex_one_database(), restore_toc_entry(), selectSourceSchema(), and setup_connection().

{
    PQExpBuffer id_return = getLocalPQExpBuffer();

    const char *cp;
    bool        need_quotes = false;

    /*
     * These checks need to match the identifier production in scan.l. Don't
     * use islower() etc.
     */
    if (quote_all_identifiers)
        need_quotes = true;
    /* slightly different rules for first character */
    else if (!((rawid[0] >= 'a' && rawid[0] <= 'z') || rawid[0] == '_'))
        need_quotes = true;
    else
    {
        /* otherwise check the entire string */
        for (cp = rawid; *cp; cp++)
        {
            if (!((*cp >= 'a' && *cp <= 'z')
                  || (*cp >= '0' && *cp <= '9')
                  || (*cp == '_')))
            {
                need_quotes = true;
                break;
            }
        }
    }

    if (!need_quotes)
    {
        /*
         * Check for keyword.  We quote keywords except for unreserved ones.
         * (In some cases we could avoid quoting a col_name or type_func_name
         * keyword, but it seems much harder than it's worth to tell that.)
         *
         * Note: ScanKeywordLookup() does case-insensitive comparison, but
         * that's fine, since we already know we have all-lower-case.
         */
        const ScanKeyword *keyword = ScanKeywordLookup(rawid,
                                                       FEScanKeywords,
                                                       NumFEScanKeywords);

        if (keyword != NULL && keyword->category != UNRESERVED_KEYWORD)
            need_quotes = true;
    }

    if (!need_quotes)
    {
        /* no quoting needed */
        appendPQExpBufferStr(id_return, rawid);
    }
    else
    {
        appendPQExpBufferChar(id_return, '\"');
        for (cp = rawid; *cp; cp++)
        {
            /*
             * Did we find a double-quote in the string? Then make this a
             * double double-quote per SQL99. Before, we put in a
             * backslash/double-quote pair. - thomas 2000-08-05
             */
            if (*cp == '\"')
                appendPQExpBufferChar(id_return, '\"');
            appendPQExpBufferChar(id_return, *cp);
        }
        appendPQExpBufferChar(id_return, '\"');
    }

    return id_return->data;
}

const char* fmtQualifiedId ( int  remoteVersion,
const char *  schema,
const char *  id 
)

Definition at line 161 of file dumputils.c.

References appendPQExpBuffer(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), fmtId(), and getLocalPQExpBuffer.

Referenced by dumpTableData_copy(), dumpTableData_insert(), getTables(), and lockTableNoWait().

{
    PQExpBuffer id_return;
    PQExpBuffer lcl_pqexp = createPQExpBuffer();

    /* Suppress schema name if fetching from pre-7.3 DB */
    if (remoteVersion >= 70300 && schema && *schema)
    {
        appendPQExpBuffer(lcl_pqexp, "%s.", fmtId(schema));
    }
    appendPQExpBuffer(lcl_pqexp, "%s", fmtId(id));

    id_return = getLocalPQExpBuffer();

    appendPQExpBuffer(id_return, "%s", lcl_pqexp->data);
    destroyPQExpBuffer(lcl_pqexp);

    return id_return->data;
}

bool parsePGArray ( const char *  atext,
char ***  itemarray,
int *  nitems 
)

Definition at line 402 of file dumputils.c.

References malloc, and NULL.

Referenced by buildACLCommands(), dumpFunc(), and getExtensionMembership().

{
    int         inputlen;
    char      **items;
    char       *strings;
    int         curitem;

    /*
     * We expect input in the form of "{item,item,item}" where any item is
     * either raw data, or surrounded by double quotes (in which case embedded
     * characters including backslashes and quotes are backslashed).
     *
     * We build the result as an array of pointers followed by the actual
     * string data, all in one malloc block for convenience of deallocation.
     * The worst-case storage need is not more than one pointer and one
     * character for each input character (consider "{,,,,,,,,,,}").
     */
    *itemarray = NULL;
    *nitems = 0;
    inputlen = strlen(atext);
    if (inputlen < 2 || atext[0] != '{' || atext[inputlen - 1] != '}')
        return false;           /* bad input */
    items = (char **) malloc(inputlen * (sizeof(char *) + sizeof(char)));
    if (items == NULL)
        return false;           /* out of memory */
    *itemarray = items;
    strings = (char *) (items + inputlen);

    atext++;                    /* advance over initial '{' */
    curitem = 0;
    while (*atext != '}')
    {
        if (*atext == '\0')
            return false;       /* premature end of string */
        items[curitem] = strings;
        while (*atext != '}' && *atext != ',')
        {
            if (*atext == '\0')
                return false;   /* premature end of string */
            if (*atext != '"')
                *strings++ = *atext++;  /* copy unquoted data */
            else
            {
                /* process quoted substring */
                atext++;
                while (*atext != '"')
                {
                    if (*atext == '\0')
                        return false;   /* premature end of string */
                    if (*atext == '\\')
                    {
                        atext++;
                        if (*atext == '\0')
                            return false;       /* premature end of string */
                    }
                    *strings++ = *atext++;      /* copy quoted data */
                }
                atext++;
            }
        }
        *strings++ = '\0';
        if (*atext == ',')
            atext++;
        curitem++;
    }
    if (atext[1] != '\0')
        return false;           /* bogus syntax (embedded '}') */
    *nitems = curitem;
    return true;
}

bool processSQLNamePattern ( PGconn conn,
PQExpBuffer  buf,
const char *  pattern,
bool  have_where,
bool  force_escape,
const char *  schemavar,
const char *  namevar,
const char *  altnamevar,
const char *  visibilityrule 
)

Definition at line 982 of file dumputils.c.

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendStringLiteralConn(), PQExpBufferData::data, encoding, i, initPQExpBuffer(), PQExpBufferData::len, NULL, pg_tolower(), PQclientEncoding(), PQmblen(), resetPQExpBuffer(), termPQExpBuffer(), and WHEREAND.

Referenced by describeAggregates(), describeFunctions(), describeOperators(), describeRoles(), describeTableDetails(), describeTablespaces(), describeTypes(), expand_schema_name_patterns(), expand_table_name_patterns(), listAllDbs(), listCasts(), listCollations(), listConversions(), listDbRoleSettings(), listDefaultACLs(), listDomains(), listEventTriggers(), listExtensionContents(), listExtensions(), listForeignDataWrappers(), listForeignServers(), listForeignTables(), listLanguages(), listSchemas(), listTables(), listTSConfigs(), listTSConfigsVerbose(), listTSDictionaries(), listTSParsers(), listTSParsersVerbose(), listTSTemplates(), listUserMappings(), objectDescription(), and permissionsList().

{
    PQExpBufferData schemabuf;
    PQExpBufferData namebuf;
    int         encoding = PQclientEncoding(conn);
    bool        inquotes;
    const char *cp;
    int         i;
    bool        added_clause = false;

#define WHEREAND() \
    (appendPQExpBufferStr(buf, have_where ? "  AND " : "WHERE "), \
     have_where = true, added_clause = true)

    if (pattern == NULL)
    {
        /* Default: select all visible objects */
        if (visibilityrule)
        {
            WHEREAND();
            appendPQExpBuffer(buf, "%s\n", visibilityrule);
        }
        return added_clause;
    }

    initPQExpBuffer(&schemabuf);
    initPQExpBuffer(&namebuf);

    /*
     * Parse the pattern, converting quotes and lower-casing unquoted letters.
     * Also, adjust shell-style wildcard characters into regexp notation.
     *
     * We surround the pattern with "^(...)$" to force it to match the whole
     * string, as per SQL practice.  We have to have parens in case the string
     * contains "|", else the "^" and "$" will be bound into the first and
     * last alternatives which is not what we want.
     *
     * Note: the result of this pass is the actual regexp pattern(s) we want
     * to execute.  Quoting/escaping into SQL literal format will be done
     * below using appendStringLiteralConn().
     */
    appendPQExpBufferStr(&namebuf, "^(");

    inquotes = false;
    cp = pattern;

    while (*cp)
    {
        char        ch = *cp;

        if (ch == '"')
        {
            if (inquotes && cp[1] == '"')
            {
                /* emit one quote, stay in inquotes mode */
                appendPQExpBufferChar(&namebuf, '"');
                cp++;
            }
            else
                inquotes = !inquotes;
            cp++;
        }
        else if (!inquotes && isupper((unsigned char) ch))
        {
            appendPQExpBufferChar(&namebuf,
                                  pg_tolower((unsigned char) ch));
            cp++;
        }
        else if (!inquotes && ch == '*')
        {
            appendPQExpBufferStr(&namebuf, ".*");
            cp++;
        }
        else if (!inquotes && ch == '?')
        {
            appendPQExpBufferChar(&namebuf, '.');
            cp++;
        }
        else if (!inquotes && ch == '.')
        {
            /* Found schema/name separator, move current pattern to schema */
            resetPQExpBuffer(&schemabuf);
            appendPQExpBufferStr(&schemabuf, namebuf.data);
            resetPQExpBuffer(&namebuf);
            appendPQExpBufferStr(&namebuf, "^(");
            cp++;
        }
        else if (ch == '$')
        {
            /*
             * Dollar is always quoted, whether inside quotes or not. The
             * reason is that it's allowed in SQL identifiers, so there's a
             * significant use-case for treating it literally, while because
             * we anchor the pattern automatically there is no use-case for
             * having it possess its regexp meaning.
             */
            appendPQExpBufferStr(&namebuf, "\\$");
            cp++;
        }
        else
        {
            /*
             * Ordinary data character, transfer to pattern
             *
             * Inside double quotes, or at all times if force_escape is true,
             * quote regexp special characters with a backslash to avoid
             * regexp errors.  Outside quotes, however, let them pass through
             * as-is; this lets knowledgeable users build regexp expressions
             * that are more powerful than shell-style patterns.
             */
            if ((inquotes || force_escape) &&
                strchr("|*+?()[]{}.^$\\", ch))
                appendPQExpBufferChar(&namebuf, '\\');
            i = PQmblen(cp, encoding);
            while (i-- && *cp)
            {
                appendPQExpBufferChar(&namebuf, *cp);
                cp++;
            }
        }
    }

    /*
     * Now decide what we need to emit.  Note there will be a leading "^(" in
     * the patterns in any case.
     */
    if (namebuf.len > 2)
    {
        /* We have a name pattern, so constrain the namevar(s) */

        appendPQExpBufferStr(&namebuf, ")$");
        /* Optimize away a "*" pattern */
        if (strcmp(namebuf.data, "^(.*)$") != 0)
        {
            WHEREAND();
            if (altnamevar)
            {
                appendPQExpBuffer(buf, "(%s ~ ", namevar);
                appendStringLiteralConn(buf, namebuf.data, conn);
                appendPQExpBuffer(buf, "\n        OR %s ~ ", altnamevar);
                appendStringLiteralConn(buf, namebuf.data, conn);
                appendPQExpBufferStr(buf, ")\n");
            }
            else
            {
                appendPQExpBuffer(buf, "%s ~ ", namevar);
                appendStringLiteralConn(buf, namebuf.data, conn);
                appendPQExpBufferChar(buf, '\n');
            }
        }
    }

    if (schemabuf.len > 2)
    {
        /* We have a schema pattern, so constrain the schemavar */

        appendPQExpBufferStr(&schemabuf, ")$");
        /* Optimize away a "*" pattern */
        if (strcmp(schemabuf.data, "^(.*)$") != 0 && schemavar)
        {
            WHEREAND();
            appendPQExpBuffer(buf, "%s ~ ", schemavar);
            appendStringLiteralConn(buf, schemabuf.data, conn);
            appendPQExpBufferChar(buf, '\n');
        }
    }
    else
    {
        /* No schema pattern given, so select only visible objects */
        if (visibilityrule)
        {
            WHEREAND();
            appendPQExpBuffer(buf, "%s\n", visibilityrule);
        }
    }

    termPQExpBuffer(&schemabuf);
    termPQExpBuffer(&namebuf);

    return added_clause;
#undef WHEREAND
}

void set_dump_section ( const char *  arg,
int *  dumpSections 
)

Definition at line 40 of file pg_backup_utils.c.

Referenced by main().

{
    /* if this is the first call, clear all the bits */
    if (*dumpSections == DUMP_UNSECTIONED)
        *dumpSections = 0;

    if (strcmp(arg, "pre-data") == 0)
        *dumpSections |= DUMP_PRE_DATA;
    else if (strcmp(arg, "data") == 0)
        *dumpSections |= DUMP_DATA;
    else if (strcmp(arg, "post-data") == 0)
        *dumpSections |= DUMP_POST_DATA;
    else
    {
        fprintf(stderr, _("%s: unrecognized section name: \"%s\"\n"),
                progname, arg);
        fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                progname);
        exit_nicely(1);
    }
}

void simple_string_list_append ( SimpleStringList list,
const char *  val 
)

Definition at line 1214 of file dumputils.c.

References SimpleStringList::head, SimpleStringListCell::next, pg_malloc(), SimpleStringList::tail, and SimpleStringListCell::val.

Referenced by main().

{
    SimpleStringListCell *cell;

    /* this calculation correctly accounts for the null trailing byte */
    cell = (SimpleStringListCell *)
        pg_malloc(sizeof(SimpleStringListCell) + strlen(val));

    cell->next = NULL;
    strcpy(cell->val, val);

    if (list->tail)
        list->tail->next = cell;
    else
        list->head = cell;
    list->tail = cell;
}

bool simple_string_list_member ( SimpleStringList list,
const char *  val 
)

Definition at line 1233 of file dumputils.c.

References SimpleStringList::head, SimpleStringListCell::next, and SimpleStringListCell::val.

Referenced by _tocEntryRequired().

{
    SimpleStringListCell *cell;

    for (cell = list->head; cell; cell = cell->next)
    {
        if (strcmp(cell->val, val) == 0)
            return true;
    }
    return false;
}


Variable Documentation

Definition at line 41 of file dumputils.c.

Referenced by fmtId(), fmtQualifiedId(), and ParallelBackupStart().

Definition at line 265 of file ruleutils.c.