diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-03-30 01:02:42 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-03-30 01:02:42 +0000 |
commit | 5f4745adf4fb2a1f933b25d7a2bc72b39fa9edfd (patch) | |
tree | e024d7d1a3eb76220378e4054bf34485812962ea /src/backend/utils | |
parent | 25004eec957853a55789398d4228d7e77d4877c1 (diff) | |
download | postgresql-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.c | 36 | ||||
-rw-r--r-- | src/backend/utils/adt/tid.c | 34 | ||||
-rw-r--r-- | src/backend/utils/adt/varlena.c | 118 |
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 * |