Logo Search packages:      
Sourcecode: postgresql-8.4 version File versions

name.c

/*-------------------------------------------------------------------------
 *
 * name.c
 *      Functions for the built-in type "name".
 *
 * name replaces char16 and is carefully implemented so that it
 * is a string of physical length NAMEDATALEN.
 * DO NOT use hard-coded constants anywhere
 * always use NAMEDATALEN as the symbolic constant!   - jolly 8/21/95
 *
 *
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *      $PostgreSQL$
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "catalog/namespace.h"
#include "catalog/pg_type.h"
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"


/*****************************************************************************
 *     USER I/O ROUTINES (none)                                                                        *
 *****************************************************************************/


/*
 *          namein      - converts "..." to internal representation
 *
 *          Note:
 *                      [Old] Currently if strlen(s) < NAMEDATALEN, the extra chars are nulls
 *                      Now, always NULL terminated
 */
Datum
namein(PG_FUNCTION_ARGS)
{
      char     *s = PG_GETARG_CSTRING(0);
      NameData   *result;
      int               len;

      len = strlen(s);
      len = pg_mbcliplen(s, len, NAMEDATALEN - 1);

      result = (NameData *) palloc0(NAMEDATALEN);
      memcpy(NameStr(*result), s, len);

      PG_RETURN_NAME(result);
}

/*
 *          nameout - converts internal representation to "..."
 */
Datum
nameout(PG_FUNCTION_ARGS)
{
      Name        s = PG_GETARG_NAME(0);

      PG_RETURN_CSTRING(pstrdup(NameStr(*s)));
}

/*
 *          namerecv                - converts external binary format to name
 */
Datum
namerecv(PG_FUNCTION_ARGS)
{
      StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
      Name        result;
      char     *str;
      int               nbytes;

      str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
      if (nbytes >= NAMEDATALEN)
            ereport(ERROR,
                        (errcode(ERRCODE_NAME_TOO_LONG),
                         errmsg("identifier too long"),
                         errdetail("Identifier must be less than %d characters.",
                                       NAMEDATALEN)));
      result = (NameData *) palloc0(NAMEDATALEN);
      memcpy(result, str, nbytes);
      pfree(str);
      PG_RETURN_NAME(result);
}

/*
 *          namesend                - converts name to binary format
 */
Datum
namesend(PG_FUNCTION_ARGS)
{
      Name        s = PG_GETARG_NAME(0);
      StringInfoData buf;

      pq_begintypsend(&buf);
      pq_sendtext(&buf, NameStr(*s), strlen(NameStr(*s)));
      PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}


/*****************************************************************************
 *     PUBLIC ROUTINES                                                                                 *
 *****************************************************************************/

/*
 *          nameeq      - returns 1 iff arguments are equal
 *          namene      - returns 1 iff arguments are not equal
 *
 *          BUGS:
 *                      Assumes that "xy\0\0a" should be equal to "xy\0b".
 *                      If not, can do the comparison backwards for efficiency.
 *
 *          namelt      - returns 1 iff a < b
 *          namele      - returns 1 iff a <= b
 *          namegt      - returns 1 iff a > b
 *          namege      - returns 1 iff a >= b
 *
 */
Datum
nameeq(PG_FUNCTION_ARGS)
{
      Name        arg1 = PG_GETARG_NAME(0);
      Name        arg2 = PG_GETARG_NAME(1);

      PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) == 0);
}

Datum
namene(PG_FUNCTION_ARGS)
{
      Name        arg1 = PG_GETARG_NAME(0);
      Name        arg2 = PG_GETARG_NAME(1);

      PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) != 0);
}

Datum
namelt(PG_FUNCTION_ARGS)
{
      Name        arg1 = PG_GETARG_NAME(0);
      Name        arg2 = PG_GETARG_NAME(1);

      PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) < 0);
}

Datum
namele(PG_FUNCTION_ARGS)
{
      Name        arg1 = PG_GETARG_NAME(0);
      Name        arg2 = PG_GETARG_NAME(1);

      PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) <= 0);
}

Datum
namegt(PG_FUNCTION_ARGS)
{
      Name        arg1 = PG_GETARG_NAME(0);
      Name        arg2 = PG_GETARG_NAME(1);

      PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) > 0);
}

Datum
namege(PG_FUNCTION_ARGS)
{
      Name        arg1 = PG_GETARG_NAME(0);
      Name        arg2 = PG_GETARG_NAME(1);

      PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) >= 0);
}


/* (see char.c for comparison/operation routines) */

int
namecpy(Name n1, Name n2)
{
      if (!n1 || !n2)
            return -1;
      strncpy(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
      return 0;
}

#ifdef NOT_USED
int
namecat(Name n1, Name n2)
{
      return namestrcat(n1, NameStr(*n2));            /* n2 can't be any longer than
                                                                         * n1 */
}
#endif

#ifdef NOT_USED
int
namecmp(Name n1, Name n2)
{
      return strncmp(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
}
#endif

int
namestrcpy(Name name, const char *str)
{
      if (!name || !str)
            return -1;
      StrNCpy(NameStr(*name), str, NAMEDATALEN);
      return 0;
}

#ifdef NOT_USED
int
namestrcat(Name name, const char *str)
{
      int               i;
      char     *p,
                     *q;

      if (!name || !str)
            return -1;
      for (i = 0, p = NameStr(*name); i < NAMEDATALEN && *p; ++i, ++p)
            ;
      for (q = str; i < NAMEDATALEN; ++i, ++p, ++q)
      {
            *p = *q;
            if (!*q)
                  break;
      }
      return 0;
}
#endif

int
namestrcmp(Name name, const char *str)
{
      if (!name && !str)
            return 0;
      if (!name)
            return -1;                    /* NULL < anything */
      if (!str)
            return 1;                     /* NULL < anything */
      return strncmp(NameStr(*name), str, NAMEDATALEN);
}


/*
 * SQL-functions CURRENT_USER, SESSION_USER
 */
Datum
current_user(PG_FUNCTION_ARGS)
{
      PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId()))));
}

Datum
session_user(PG_FUNCTION_ARGS)
{
      PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetSessionUserId()))));
}


/*
 * SQL-functions CURRENT_SCHEMA, CURRENT_SCHEMAS
 */
Datum
current_schema(PG_FUNCTION_ARGS)
{
      List     *search_path = fetch_search_path(false);
      char     *nspname;

      if (search_path == NIL)
            PG_RETURN_NULL();
      nspname = get_namespace_name(linitial_oid(search_path));
      list_free(search_path);
      if (!nspname)
            PG_RETURN_NULL();       /* recently-deleted namespace? */
      PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(nspname)));
}

Datum
current_schemas(PG_FUNCTION_ARGS)
{
      List     *search_path = fetch_search_path(PG_GETARG_BOOL(0));
      ListCell   *l;
      Datum    *names;
      int               i;
      ArrayType  *array;

      names = (Datum *) palloc(list_length(search_path) * sizeof(Datum));
      i = 0;
      foreach(l, search_path)
      {
            char     *nspname;

            nspname = get_namespace_name(lfirst_oid(l));
            if (nspname)                  /* watch out for deleted namespace */
            {
                  names[i] = DirectFunctionCall1(namein, CStringGetDatum(nspname));
                  i++;
            }
      }
      list_free(search_path);

      array = construct_array(names, i,
                                          NAMEOID,
                                          NAMEDATALEN,            /* sizeof(Name) */
                                          false,            /* Name is not by-val */
                                          'c');       /* alignment of Name */

      PG_RETURN_POINTER(array);
}

Generated by  Doxygen 1.6.0   Back to index