aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-03-30 01:02:42 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-03-30 01:02:42 +0000
commit5f4745adf4fb2a1f933b25d7a2bc72b39fa9edfd (patch)
treee024d7d1a3eb76220378e4054bf34485812962ea /src/backend/utils
parent25004eec957853a55789398d4228d7e77d4877c1 (diff)
downloadpostgresql-5f4745adf4fb2a1f933b25d7a2bc72b39fa9edfd.tar.gz
postgresql-5f4745adf4fb2a1f933b25d7a2bc72b39fa9edfd.zip
Further cleanups for relations in schemas: teach nextval and other
sequence functions how to cope with qualified names. Same code is also used for int4notin, currtid_byrelname, pgstattuple. Also, move TOAST tables into special pg_toast namespace.
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/not_in.c36
-rw-r--r--src/backend/utils/adt/tid.c34
-rw-r--r--src/backend/utils/adt/varlena.c118
3 files changed, 149 insertions, 39 deletions
diff --git a/src/backend/utils/adt/not_in.c b/src/backend/utils/adt/not_in.c
index 8c3ca1b73bc..970b1fc9c29 100644
--- a/src/backend/utils/adt/not_in.c
+++ b/src/backend/utils/adt/not_in.c
@@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -25,7 +25,9 @@
*/
#include "postgres.h"
+
#include "access/heapam.h"
+#include "catalog/namespace.h"
#include "utils/builtins.h"
static int my_varattno(Relation rd, char *a);
@@ -39,43 +41,39 @@ int4notin(PG_FUNCTION_ARGS)
{
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);
diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c
index 623d3178e00..9f3dcf8fa16 100644
--- a/src/backend/utils/adt/tid.c
+++ b/src/backend/utils/adt/tid.c
@@ -8,7 +8,7 @@
*
*
* 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().
@@ -19,6 +19,7 @@
#include "postgres.h"
#include "access/heapam.h"
+#include "catalog/namespace.h"
#include "utils/builtins.h"
#define DatumGetItemPointer(X) ((ItemPointer) DatumGetPointer(X))
@@ -146,14 +147,13 @@ currtid_byreloid(PG_FUNCTION_ARGS)
*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);
}
@@ -164,23 +164,19 @@ currtid_byrelname(PG_FUNCTION_ARGS)
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);
}
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index b10ec7d6855..ce3e8dc254d 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -1039,6 +1039,122 @@ name_text(PG_FUNCTION_ARGS)
}
+/*
+ * 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
*