Header And Logo

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

Functions

collationcmds.h File Reference

#include "nodes/parsenodes.h"
Include dependency graph for collationcmds.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

Oid DefineCollation (List *names, List *parameters)
void IsThereCollationInNamespace (const char *collname, Oid nspOid)

Function Documentation

Oid DefineCollation ( List names,
List parameters 
)

Definition at line 41 of file collationcmds.c.

References ACL_CREATE, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_OK, check_encoding_locale_matches(), CollationCreate(), COLLOID, CommandCounterIncrement(), defGetQualifiedName(), defGetString(), DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, get_collation_oid(), get_namespace_name(), GetDatabaseEncoding(), GETSTRUCT, GetUserId(), HeapTupleIsValid, lfirst, list_length(), NameStr, ObjectIdGetDatum, pg_namespace_aclcheck(), pg_newlocale_from_collation(), pg_strcasecmp(), pstrdup(), QualifiedNameGetCreationNamespace(), ReleaseSysCache(), and SearchSysCache1.

Referenced by ProcessUtilitySlow().

{
    char       *collName;
    Oid         collNamespace;
    AclResult   aclresult;
    ListCell   *pl;
    DefElem    *fromEl = NULL;
    DefElem    *localeEl = NULL;
    DefElem    *lccollateEl = NULL;
    DefElem    *lcctypeEl = NULL;
    char       *collcollate = NULL;
    char       *collctype = NULL;
    Oid         newoid;

    collNamespace = QualifiedNameGetCreationNamespace(names, &collName);

    aclresult = pg_namespace_aclcheck(collNamespace, GetUserId(), ACL_CREATE);
    if (aclresult != ACLCHECK_OK)
        aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
                       get_namespace_name(collNamespace));

    foreach(pl, parameters)
    {
        DefElem    *defel = (DefElem *) lfirst(pl);
        DefElem   **defelp;

        if (pg_strcasecmp(defel->defname, "from") == 0)
            defelp = &fromEl;
        else if (pg_strcasecmp(defel->defname, "locale") == 0)
            defelp = &localeEl;
        else if (pg_strcasecmp(defel->defname, "lc_collate") == 0)
            defelp = &lccollateEl;
        else if (pg_strcasecmp(defel->defname, "lc_ctype") == 0)
            defelp = &lcctypeEl;
        else
        {
            ereport(ERROR,
                    (errcode(ERRCODE_SYNTAX_ERROR),
                     errmsg("collation attribute \"%s\" not recognized",
                            defel->defname)));
            break;
        }

        *defelp = defel;
    }

    if ((localeEl && (lccollateEl || lcctypeEl))
        || (fromEl && list_length(parameters) != 1))
        ereport(ERROR,
                (errcode(ERRCODE_SYNTAX_ERROR),
                 errmsg("conflicting or redundant options")));

    if (fromEl)
    {
        Oid         collid;
        HeapTuple   tp;

        collid = get_collation_oid(defGetQualifiedName(fromEl), false);
        tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
        if (!HeapTupleIsValid(tp))
            elog(ERROR, "cache lookup failed for collation %u", collid);

        collcollate = pstrdup(NameStr(((Form_pg_collation) GETSTRUCT(tp))->collcollate));
        collctype = pstrdup(NameStr(((Form_pg_collation) GETSTRUCT(tp))->collctype));

        ReleaseSysCache(tp);
    }

    if (localeEl)
    {
        collcollate = defGetString(localeEl);
        collctype = defGetString(localeEl);
    }

    if (lccollateEl)
        collcollate = defGetString(lccollateEl);

    if (lcctypeEl)
        collctype = defGetString(lcctypeEl);

    if (!collcollate)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                 errmsg("parameter \"lc_collate\" must be specified")));

    if (!collctype)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                 errmsg("parameter \"lc_ctype\" must be specified")));

    check_encoding_locale_matches(GetDatabaseEncoding(), collcollate, collctype);

    newoid = CollationCreate(collName,
                             collNamespace,
                             GetUserId(),
                             GetDatabaseEncoding(),
                             collcollate,
                             collctype);

    /* check that the locales can be loaded */
    CommandCounterIncrement();
    (void) pg_newlocale_from_collation(newoid);

    return newoid;
}

void IsThereCollationInNamespace ( const char *  collname,
Oid  nspOid 
)

Definition at line 154 of file collationcmds.c.

References COLLNAMEENCNSP, CStringGetDatum, ereport, errcode(), errmsg(), ERROR, get_namespace_name(), GetDatabaseEncoding(), GetDatabaseEncodingName(), Int32GetDatum, ObjectIdGetDatum, and SearchSysCacheExists3.

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().

{
    /* make sure the name doesn't already exist in new schema */
    if (SearchSysCacheExists3(COLLNAMEENCNSP,
                              CStringGetDatum(collname),
                              Int32GetDatum(GetDatabaseEncoding()),
                              ObjectIdGetDatum(nspOid)))
        ereport(ERROR,
                (errcode(ERRCODE_DUPLICATE_OBJECT),
                 errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
                        collname, GetDatabaseEncodingName(),
                        get_namespace_name(nspOid))));

    /* mustn't match an any-encoding entry, either */
    if (SearchSysCacheExists3(COLLNAMEENCNSP,
                              CStringGetDatum(collname),
                              Int32GetDatum(-1),
                              ObjectIdGetDatum(nspOid)))
        ereport(ERROR,
                (errcode(ERRCODE_DUPLICATE_OBJECT),
                 errmsg("collation \"%s\" already exists in schema \"%s\"",
                        collname, get_namespace_name(nspOid))));
}