pgstattuple can be called as a function:
- pgstattuple(NAME) RETURNS FLOAT8
+ pgstattuple(TEXT) RETURNS FLOAT8
The argument is the table name. pgstattuple returns the percentage
of the "dead" tuples of a table.
/*
- * $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.4 2002/03/06 06:09:10 momjian Exp $
+ * $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.5 2002/03/30 01:02:41 tgl Exp $
*
* Copyright (c) 2001 Tatsuo Ishii
*
#include "fmgr.h"
#include "access/heapam.h"
#include "access/transam.h"
+#include "catalog/namespace.h"
+#include "utils/builtins.h"
+
PG_FUNCTION_INFO_V1(pgstattuple);
Datum
pgstattuple(PG_FUNCTION_ARGS)
{
- Name p = PG_GETARG_NAME(0);
-
+ text *relname = PG_GETARG_TEXT_P(0);
+ RangeVar *relrv;
Relation rel;
HeapScanDesc scan;
HeapTuple tuple;
uint64 dead_tuple_count = 0;
double tuple_percent;
double dead_tuple_percent;
-
uint64 free_space = 0; /* free/reusable space in bytes */
double free_percent; /* free/reusable space in % */
- rel = heap_openr(NameStr(*p), AccessShareLock);
+ relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname,
+ "pgstattuple"));
+ rel = heap_openrv(relrv, AccessShareLock);
+
nblocks = RelationGetNumberOfBlocks(rel);
scan = heap_beginscan(rel, false, SnapshotAny, 0, NULL);
-DROP FUNCTION pgstattuple(NAME);
-CREATE FUNCTION pgstattuple(NAME) RETURNS FLOAT8
+DROP FUNCTION pgstattuple(text);
+CREATE FUNCTION pgstattuple(text) RETURNS float8
AS 'MODULE_PATHNAME', 'pgstattuple'
LANGUAGE 'c' WITH (isstrict);
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.2 2002/03/29 19:06:01 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.3 2002/03/30 01:02:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* RangeVarGetCreationNamespace
* Given a RangeVar describing a to-be-created relation,
* choose which namespace to create it in.
+ *
+ * Note: calling this may result in a CommandCounterIncrement operation.
+ * That will happen on the first request for a temp table in any particular
+ * backend run; we will need to either create or clean out the temp schema.
*/
Oid
RangeVarGetCreationNamespace(const RangeVar *newRelation)
return get_relname_relid(relname, PG_CATALOG_NAMESPACE);
}
+/*
+ * TypenameGetTypid
+ * Try to resolve an unqualified datatype name.
+ * Returns OID if type found in search path, else InvalidOid.
+ */
+Oid
+TypenameGetTypid(const char *typname)
+{
+ /* XXX wrong, should use namespace search */
+ return GetSysCacheOid(TYPENAMENSP,
+ PointerGetDatum(typname),
+ ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 0, 0);
+}
+
/*
* QualifiedNameGetCreationNamespace
* Given a possibly-qualified name for an object (in List-of-Values
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.167 2002/03/29 19:06:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.168 2002/03/30 01:02:41 tgl Exp $
*
* NOTES
* The PerformAddAttribute() code, like most of the relation
tupdesc->attrs[2]->attstorage = 'p';
/*
- * Note: the toast relation is considered a "normal" relation even if
- * its master relation is a temp table. There cannot be any naming
- * collision, and the toast rel will be destroyed when its master is,
- * so there's no need to handle the toast rel as temp.
+ * Note: the toast relation is placed in the regular pg_toast namespace
+ * even if its master relation is a temp table. There cannot be any
+ * naming collision, and the toast rel will be destroyed when its master
+ * is, so there's no need to handle the toast rel as temp.
*/
toast_relid = heap_create_with_catalog(toast_relname,
- RelationGetNamespace(rel),
+ PG_TOAST_NAMESPACE,
tupdesc,
RELKIND_TOASTVALUE, false,
false, true);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.75 2002/03/29 19:06:07 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.76 2002/03/30 01:02:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include <ctype.h>
-
#include "access/heapam.h"
+#include "catalog/namespace.h"
#include "catalog/pg_type.h"
#include "commands/creatinh.h"
#include "commands/sequence.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/int8.h"
-#ifdef MULTIBYTE
-#include "mb/pg_wchar.h"
-#endif
#define SEQ_MAGIC 0x1717
typedef struct SeqTableData
{
- char *name;
Oid relid;
Relation rel; /* NULL if rel is not open in cur xact */
int64 cached;
static SeqTable seqtab = NULL;
-static char *get_seq_name(text *seqin);
-static SeqTable init_sequence(char *caller, char *name);
+static SeqTable init_sequence(char *caller, RangeVar *relation);
static Form_pg_sequence read_info(char *caller, SeqTable elm, Buffer *buf);
static void init_params(CreateSeqStmt *seq, Form_pg_sequence new);
static int64 get_param(DefElem *def);
-static void do_setval(char *seqname, int64 next, bool iscalled);
+static void do_setval(RangeVar *sequence, int64 next, bool iscalled);
/*
* DefineSequence
nextval(PG_FUNCTION_ARGS)
{
text *seqin = PG_GETARG_TEXT_P(0);
- char *seqname = get_seq_name(seqin);
+ RangeVar *sequence;
SeqTable elm;
Buffer buf;
Page page;
rescnt = 0;
bool logit = false;
+ sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
+ "nextval"));
+
/* open and AccessShareLock sequence */
- elm = init_sequence("nextval", seqname);
+ elm = init_sequence("nextval", sequence);
if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
elog(ERROR, "%s.nextval: you don't have permissions to set sequence %s",
- seqname, seqname);
-
- pfree(seqname);
+ sequence->relname, sequence->relname);
if (elm->last != elm->cached) /* some numbers were cached */
{
break; /* stop fetching */
if (!seq->is_cycled)
elog(ERROR, "%s.nextval: reached MAXVALUE (" INT64_FORMAT ")",
- elm->name, maxv);
+ sequence->relname, maxv);
next = minv;
}
else
break; /* stop fetching */
if (!seq->is_cycled)
elog(ERROR, "%s.nextval: reached MINVALUE (" INT64_FORMAT ")",
- elm->name, minv);
+ sequence->relname, minv);
next = maxv;
}
else
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
if (WriteBuffer(buf) == STATUS_ERROR)
- elog(ERROR, "%s.nextval: WriteBuffer failed", elm->name);
+ elog(ERROR, "%s.nextval: WriteBuffer failed", sequence->relname);
PG_RETURN_INT64(result);
}
currval(PG_FUNCTION_ARGS)
{
text *seqin = PG_GETARG_TEXT_P(0);
- char *seqname = get_seq_name(seqin);
+ RangeVar *sequence;
SeqTable elm;
int64 result;
+ sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
+ "currval"));
+
/* open and AccessShareLock sequence */
- elm = init_sequence("currval", seqname);
+ elm = init_sequence("currval", sequence);
if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
elog(ERROR, "%s.currval: you don't have permissions to read sequence %s",
- seqname, seqname);
+ sequence->relname, sequence->relname);
if (elm->increment == 0) /* nextval/read_info were not called */
elog(ERROR, "%s.currval is not yet defined in this session",
- seqname);
+ sequence->relname);
result = elm->last;
- pfree(seqname);
-
PG_RETURN_INT64(result);
}
* sequence.
*/
static void
-do_setval(char *seqname, int64 next, bool iscalled)
+do_setval(RangeVar *sequence, int64 next, bool iscalled)
{
SeqTable elm;
Buffer buf;
Form_pg_sequence seq;
/* open and AccessShareLock sequence */
- elm = init_sequence("setval", seqname);
+ elm = init_sequence("setval", sequence);
if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
elog(ERROR, "%s.setval: you don't have permissions to set sequence %s",
- seqname, seqname);
+ sequence->relname, sequence->relname);
/* lock page' buffer and read tuple */
seq = read_info("setval", elm, &buf);
if ((next < seq->min_value) || (next > seq->max_value))
elog(ERROR, "%s.setval: value " INT64_FORMAT " is out of bounds (" INT64_FORMAT "," INT64_FORMAT ")",
- seqname, next, seq->min_value, seq->max_value);
+ sequence->relname, next, seq->min_value, seq->max_value);
/* save info in local cache */
elm->last = next; /* last returned number */
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
if (WriteBuffer(buf) == STATUS_ERROR)
- elog(ERROR, "%s.setval: WriteBuffer failed", seqname);
-
- pfree(seqname);
+ elog(ERROR, "%s.setval: WriteBuffer failed", sequence->relname);
}
/*
{
text *seqin = PG_GETARG_TEXT_P(0);
int64 next = PG_GETARG_INT64(1);
- char *seqname = get_seq_name(seqin);
+ RangeVar *sequence;
+
+ sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
+ "setval"));
- do_setval(seqname, next, true);
+ do_setval(sequence, next, true);
PG_RETURN_INT64(next);
}
text *seqin = PG_GETARG_TEXT_P(0);
int64 next = PG_GETARG_INT64(1);
bool iscalled = PG_GETARG_BOOL(2);
- char *seqname = get_seq_name(seqin);
+ RangeVar *sequence;
- do_setval(seqname, next, iscalled);
+ sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
+ "setval"));
- PG_RETURN_INT64(next);
-}
+ do_setval(sequence, next, iscalled);
-/*
- * Given a 'text' parameter to a sequence function, extract the actual
- * sequence name. We downcase the name if it's not double-quoted,
- * and truncate it if it's too long.
- *
- * This is a kluge, really --- should be able to write nextval(seqrel).
- */
-static char *
-get_seq_name(text *seqin)
-{
- char *rawname = DatumGetCString(DirectFunctionCall1(textout,
- PointerGetDatum(seqin)));
- int rawlen = strlen(rawname);
- char *seqname;
-
- if (rawlen >= 2 &&
- rawname[0] == '\"' && rawname[rawlen - 1] == '\"')
- {
- /* strip off quotes, keep case */
- rawname[rawlen - 1] = '\0';
- seqname = pstrdup(rawname + 1);
- pfree(rawname);
- }
- else
- {
- seqname = rawname;
-
- /*
- * It's important that this match the identifier downcasing code
- * used by backend/parser/scan.l.
- */
- for (; *rawname; rawname++)
- {
- if (isupper((unsigned char) *rawname))
- *rawname = tolower((unsigned char) *rawname);
- }
- }
-
- /* Truncate name if it's overlength; again, should match scan.l */
- if (strlen(seqname) >= NAMEDATALEN)
- {
-#ifdef MULTIBYTE
- int len;
-
- len = pg_mbcliplen(seqname, rawlen, NAMEDATALEN - 1);
- seqname[len] = '\0';
-#else
- seqname[NAMEDATALEN - 1] = '\0';
-#endif
- }
-
- return seqname;
+ PG_RETURN_INT64(next);
}
static Form_pg_sequence
if (elm->rel->rd_nblocks > 1)
elog(ERROR, "%s.%s: invalid number of blocks in sequence",
- elm->name, caller);
+ RelationGetRelationName(elm->rel), caller);
*buf = ReadBuffer(elm->rel, 0);
if (!BufferIsValid(*buf))
- elog(ERROR, "%s.%s: ReadBuffer failed", elm->name, caller);
+ elog(ERROR, "%s.%s: ReadBuffer failed",
+ RelationGetRelationName(elm->rel), caller);
LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);
sm = (sequence_magic *) PageGetSpecialPointer(page);
if (sm->magic != SEQ_MAGIC)
- elog(ERROR, "%s.%s: bad magic (%08X)", elm->name, caller, sm->magic);
+ elog(ERROR, "%s.%s: bad magic (%08X)",
+ RelationGetRelationName(elm->rel), caller, sm->magic);
lp = PageGetItemId(page, FirstOffsetNumber);
Assert(ItemIdIsUsed(lp));
static SeqTable
-init_sequence(char *caller, char *name)
+init_sequence(char *caller, RangeVar *relation)
{
+ Oid relid = RangeVarGetRelid(relation, false);
SeqTable elm,
prev = (SeqTable) NULL;
Relation seqrel;
-
- /* Look to see if we already have a seqtable entry for name */
+
+ /* Look to see if we already have a seqtable entry for relation */
for (elm = seqtab; elm != (SeqTable) NULL; elm = elm->next)
{
- if (strcmp(elm->name, name) == 0)
+ if (elm->relid == relid)
break;
prev = elm;
}
return elm;
/* Else open and check it */
- seqrel = heap_openr(name, AccessShareLock);
+ seqrel = heap_open(relid, AccessShareLock);
if (seqrel->rd_rel->relkind != RELKIND_SEQUENCE)
- elog(ERROR, "%s.%s: %s is not a sequence", name, caller, name);
+ elog(ERROR, "%s.%s: %s is not a sequence",
+ relation->relname, caller, relation->relname);
+ /*
+ * If elm exists but elm->rel is NULL, the seqtable entry is left over
+ * from a previous xact -- update the entry and reuse it.
+ *
+ * NOTE: seqtable entries remain in the list for the life of a backend.
+ * If the sequence itself is deleted then the entry becomes wasted memory,
+ * but it's small enough that this should not matter.
+ */
if (elm != (SeqTable) NULL)
{
- /*
- * We are using a seqtable entry left over from a previous xact;
- * must check for relid change.
- */
elm->rel = seqrel;
- if (RelationGetRelid(seqrel) != elm->relid)
- {
- elog(WARNING, "%s.%s: sequence was re-created",
- name, caller);
- elm->relid = RelationGetRelid(seqrel);
- elm->cached = elm->last = elm->increment = 0;
- }
}
else
{
elm = (SeqTable) malloc(sizeof(SeqTableData));
if (elm == NULL)
elog(ERROR, "Memory exhausted in init_sequence");
- elm->name = strdup(name);
- if (elm->name == NULL)
- elog(ERROR, "Memory exhausted in init_sequence");
elm->rel = seqrel;
- elm->relid = RelationGetRelid(seqrel);
+ elm->relid = relid;
elm->cached = elm->last = elm->increment = 0;
elm->next = (SeqTable) NULL;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.38 2002/03/29 19:06:12 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.39 2002/03/30 01:02:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/namespace.h"
-#include "catalog/pg_namespace.h"
#include "catalog/pg_type.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
if (schemaname)
{
+ /* Look in specific schema only */
Oid namespaceId;
namespaceId = GetSysCacheOid(NAMESPACENAME,
}
else
{
- /* XXX wrong, should use namespace search */
- restype = GetSysCacheOid(TYPENAMENSP,
- PointerGetDatum(typname),
- ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
- 0, 0);
+ /* Unqualified type name, so search the search path */
+ restype = TypenameGetTypid(typname);
}
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.27 2001/10/25 05:49:45 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.28 2002/03/30 01:02:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
#include "postgres.h"
+
#include "access/heapam.h"
+#include "catalog/namespace.h"
#include "utils/builtins.h"
static int my_varattno(Relation rd, char *a);
{
int32 not_in_arg = PG_GETARG_INT32(0);
text *relation_and_attr = PG_GETARG_TEXT_P(1);
+ List *names;
+ int nnames;
+ RangeVar *relrv;
+ char *attribute;
Relation relation_to_scan;
int32 integer_value;
HeapTuple current_tuple;
HeapScanDesc scan_descriptor;
bool isNull,
retval;
- int attrid,
- strlength;
- char *relation,
- *attribute;
- char my_copy[NAMEDATALEN * 2 + 2];
+ int attrid;
Datum value;
- /* make a null-terminated copy of text */
- strlength = VARSIZE(relation_and_attr) - VARHDRSZ;
- if (strlength >= sizeof(my_copy))
- strlength = sizeof(my_copy) - 1;
- memcpy(my_copy, VARDATA(relation_and_attr), strlength);
- my_copy[strlength] = '\0';
+ /* Parse the argument */
- relation = (char *) strtok(my_copy, ".");
- attribute = (char *) strtok(NULL, ".");
- if (attribute == NULL)
+ names = textToQualifiedNameList(relation_and_attr, "int4notin");
+ nnames = length(names);
+ if (nnames < 2)
elog(ERROR, "int4notin: must provide relationname.attributename");
+ attribute = strVal(nth(nnames-1, names));
+ names = ltruncate(nnames-1, names);
+ relrv = makeRangeVarFromNameList(names);
/* Open the relation and get a relation descriptor */
- relation_to_scan = heap_openr(relation, AccessShareLock);
+ relation_to_scan = heap_openrv(relrv, AccessShareLock);
/* Find the column to search */
attrid = my_varattno(relation_to_scan, attribute);
if (attrid < 0)
- {
elog(ERROR, "int4notin: unknown attribute %s for relation %s",
- attribute, relation);
- }
+ attribute, RelationGetRelationName(relation_to_scan));
scan_descriptor = heap_beginscan(relation_to_scan, false, SnapshotNow,
0, (ScanKey) NULL);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.28 2001/10/25 05:49:45 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.29 2002/03/30 01:02:41 tgl Exp $
*
* NOTES
* input routine largely stolen from boxin().
#include "postgres.h"
#include "access/heapam.h"
+#include "catalog/namespace.h"
#include "utils/builtins.h"
#define DatumGetItemPointer(X) ((ItemPointer) DatumGetPointer(X))
*result = Current_last_tid;
PG_RETURN_ITEMPOINTER(result);
}
+
+ rel = heap_open(reloid, AccessShareLock);
+
ItemPointerCopy(tid, result);
- if ((rel = heap_open(reloid, AccessShareLock)) != NULL)
- {
- heap_get_latest_tid(rel, SnapshotNow, result);
- heap_close(rel, AccessShareLock);
- }
- else
- elog(ERROR, "Relation %u not found", reloid);
+ heap_get_latest_tid(rel, SnapshotNow, result);
+
+ heap_close(rel, AccessShareLock);
PG_RETURN_ITEMPOINTER(result);
}
text *relname = PG_GETARG_TEXT_P(0);
ItemPointer tid = PG_GETARG_ITEMPOINTER(1);
ItemPointer result;
- char *str;
+ RangeVar *relrv;
Relation rel;
- str = DatumGetCString(DirectFunctionCall1(textout,
- PointerGetDatum(relname)));
+ relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname,
+ "currtid_byrelname"));
+ rel = heap_openrv(relrv, AccessShareLock);
result = (ItemPointer) palloc(sizeof(ItemPointerData));
ItemPointerCopy(tid, result);
- if ((rel = heap_openr(str, AccessShareLock)) != NULL)
- {
- heap_get_latest_tid(rel, SnapshotNow, result);
- heap_close(rel, AccessShareLock);
- }
- else
- elog(ERROR, "Relation %s not found", str);
- pfree(str);
+ heap_get_latest_tid(rel, SnapshotNow, result);
+
+ heap_close(rel, AccessShareLock);
PG_RETURN_ITEMPOINTER(result);
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.79 2002/03/05 05:33:19 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.80 2002/03/30 01:02:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
}
+/*
+ * textToQualifiedNameList - convert a text object to list of names
+ *
+ * This implements the input parsing needed by nextval() and other
+ * functions that take a text parameter representing a qualified name.
+ * We split the name at dots, downcase if not double-quoted, and
+ * truncate names if they're too long.
+ *
+ * This is a kluge, really, and exists only for historical reasons.
+ * A better notation for such functions would be nextval(relname).
+ */
+List *
+textToQualifiedNameList(text *textval, const char *caller)
+{
+ char *rawname;
+ char *nextp;
+ List *result = NIL;
+
+ /* Convert to C string (handles possible detoasting). */
+ /* Note we rely on being able to modify rawname below. */
+ rawname = DatumGetCString(DirectFunctionCall1(textout,
+ PointerGetDatum(textval)));
+ nextp = rawname;
+
+ do
+ {
+ char *curname;
+ char *endp;
+ char *cp;
+ int curlen;
+
+ if (*nextp == '\"')
+ {
+ /* Quoted name --- collapse quote-quote pairs, no downcasing */
+ curname = nextp + 1;
+ for (;;)
+ {
+ endp = strchr(nextp + 1, '\"');
+ if (endp == NULL)
+ elog(ERROR, "%s: invalid quoted name: mismatched quotes",
+ caller);
+ if (endp[1] != '\"')
+ break; /* found end of quoted name */
+ /* Collapse adjacent quotes into one quote, and look again */
+ memmove(endp, endp+1, strlen(endp));
+ nextp = endp;
+ }
+ *endp = '\0';
+ nextp = endp + 1;
+ if (*nextp)
+ {
+ if (*nextp != '.')
+ elog(ERROR, "%s: invalid name syntax",
+ caller);
+ nextp++;
+ if (*nextp == '\0')
+ elog(ERROR, "%s: invalid name syntax",
+ caller);
+ }
+ }
+ else
+ {
+ /* Unquoted name --- extends to next dot */
+ if (*nextp == '\0') /* empty name not okay here */
+ elog(ERROR, "%s: invalid name syntax",
+ caller);
+ curname = nextp;
+ endp = strchr(nextp, '.');
+ if (endp)
+ {
+ *endp = '\0';
+ nextp = endp + 1;
+ if (*nextp == '\0')
+ elog(ERROR, "%s: invalid name syntax",
+ caller);
+ }
+ else
+ nextp = nextp + strlen(nextp);
+ /*
+ * It's important that this match the identifier downcasing code
+ * used by backend/parser/scan.l.
+ */
+ for (cp = curname; *cp; cp++)
+ {
+ if (isupper((unsigned char) *cp))
+ *cp = tolower((unsigned char) *cp);
+ }
+ }
+
+ /* Truncate name if it's overlength; again, should match scan.l */
+ curlen = strlen(curname);
+ if (curlen >= NAMEDATALEN)
+ {
+#ifdef MULTIBYTE
+ curlen = pg_mbcliplen(curname, curlen, NAMEDATALEN - 1);
+ curname[curlen] = '\0';
+#else
+ curname[NAMEDATALEN - 1] = '\0';
+#endif
+ }
+
+ /*
+ * Finished isolating current name --- add it to list
+ */
+ result = lappend(result, makeString(pstrdup(curname)));
+ /*
+ * Loop back if we found a dot
+ */
+ } while (*nextp);
+
+ pfree(rawname);
+
+ return result;
+}
+
+
/*****************************************************************************
* Comparison Functions used for bytea
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: namespace.h,v 1.2 2002/03/29 19:06:18 tgl Exp $
+ * $Id: namespace.h,v 1.3 2002/03/30 01:02:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern Oid RelnameGetRelid(const char *relname);
+extern Oid TypenameGetTypid(const char *typname);
+
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
extern RangeVar *makeRangeVarFromNameList(List *names);
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_namespace.h,v 1.1 2002/03/22 21:34:44 tgl Exp $
+ * $Id: pg_namespace.h,v 1.2 2002/03/30 01:02:42 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
DATA(insert OID = 11 ( "pg_catalog" PGUID "{=r}" ));
DESCR("System catalog namespace");
#define PG_CATALOG_NAMESPACE 11
+DATA(insert OID = 99 ( "pg_toast" PGUID "{=r}" ));
+DESCR("Reserved namespace for TOAST tables");
+#define PG_TOAST_NAMESPACE 99
+DATA(insert OID = 2071 ( "pg_public" PGUID "{=rw}" ));
+DESCR("Standard public namespace");
+#define PG_PUBLIC_NAMESPACE 2071
/*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: builtins.h,v 1.173 2002/03/22 02:56:37 tgl Exp $
+ * $Id: builtins.h,v 1.174 2002/03/30 01:02:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern Datum name_text(PG_FUNCTION_ARGS);
extern Datum text_name(PG_FUNCTION_ARGS);
extern int varstr_cmp(char *arg1, int len1, char *arg2, int len2);
+extern List *textToQualifiedNameList(text *textval, const char *caller);
extern Datum byteain(PG_FUNCTION_ARGS);
extern Datum byteaout(PG_FUNCTION_ARGS);
INSERT INTO tmp VALUES (5, '!check failed', null);
INSERT INTO tmp VALUES (null, 'try again', null);
INSERT INTO INSERT_TBL(y) select yd from tmp;
-WARNING: insert_seq.nextval: sequence was re-created
SELECT '' AS three, * FROM INSERT_TBL;
three | x | y | z
-------+---+---------------+----