Alter string format used for integer and OID lists in stored rules.
authorTom Lane
Sat, 8 May 2004 21:21:18 +0000 (21:21 +0000)
committerTom Lane
Sat, 8 May 2004 21:21:18 +0000 (21:21 +0000)
This simplifies and speeds up the reader by letting it get the representation
right the first time, rather than correcting it after-the-fact.  Also,
after int and OID lists become separate node types per Neil's pending
patch, this will let us treat these lists as just plain Nodes instead
of requiring separate read/write macros the way we have now.

src/backend/nodes/outfuncs.c
src/backend/nodes/print.c
src/backend/nodes/read.c
src/backend/nodes/readfuncs.c
src/include/catalog/catversion.h

index 788e7dc5afa902eb275e863d4ab1ff0e9f5d225f..9139a9bec54b004e15f67b1107814e97dac075fc 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.234 2004/05/06 14:01:33 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.235 2004/05/08 21:21:18 tgl Exp $
  *
  * NOTES
  *   Every node type that can appear in stored rules' parsetrees *must*
@@ -155,6 +155,7 @@ _outIntList(StringInfo str, List *list)
    List       *l;
 
    appendStringInfoChar(str, '(');
+   appendStringInfoChar(str, 'i');
    foreach(l, list)
        appendStringInfo(str, " %d", lfirsti(l));
    appendStringInfoChar(str, ')');
@@ -170,6 +171,7 @@ _outOidList(StringInfo str, List *list)
    List       *l;
 
    appendStringInfoChar(str, '(');
+   appendStringInfoChar(str, 'o');
    foreach(l, list)
        appendStringInfo(str, " %u", lfirsto(l));
    appendStringInfoChar(str, ')');
@@ -179,8 +181,9 @@ _outOidList(StringInfo str, List *list)
  * _outBitmapset -
  *    converts a bitmap set of integers
  *
- * Note: for historical reasons, the output is formatted exactly like
- * an integer List would be.
+ * Note: the output format is "(b int int ...)", similar to an integer List.
+ * Currently bitmapsets do not appear in any node type that is stored in
+ * rules, so there is no support in readfuncs.c for reading this format.
  */
 static void
 _outBitmapset(StringInfo str, Bitmapset *bms)
@@ -189,6 +192,7 @@ _outBitmapset(StringInfo str, Bitmapset *bms)
    int         x;
 
    appendStringInfoChar(str, '(');
+   appendStringInfoChar(str, 'b');
    tmpset = bms_copy(bms);
    while ((x = bms_first_member(tmpset)) >= 0)
        appendStringInfo(str, " %d", x);
index 074a83890232ae205712e7335e6cd144df26c719..14f73b1860ea2d12a37b9dac644d915d7736c6d5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/print.c,v 1.65 2003/11/29 19:51:49 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/print.c,v 1.66 2004/05/08 21:21:18 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -194,12 +194,20 @@ pretty_format_node_dump(const char *dump)
                    }
                    j = indentDist - 1;
                    /* j will equal indentDist on next loop iteration */
+                   /* suppress whitespace just after } */
+                   while (dump[i+1] == ' ')
+                       i++;
                    break;
                case ')':
-                   /* force line break after ')' */
-                   line[j + 1] = '\0';
-                   appendStringInfo(&str, "%s\n", line);
-                   j = indentDist - 1;
+                   /* force line break after ), unless another ) follows */
+                   if (dump[i+1] != ')')
+                   {
+                       line[j + 1] = '\0';
+                       appendStringInfo(&str, "%s\n", line);
+                       j = indentDist - 1;
+                       while (dump[i+1] == ' ')
+                           i++;
+                   }
                    break;
                case '{':
                    /* force line break before { */
index 402c9991131f9e97a23b9bddf5db2c0207f0b7c2..e90b413591c22f2bec2097dc55397b5d9879f1b5 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/read.c,v 1.40 2004/05/06 14:01:33 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/read.c,v 1.41 2004/05/08 21:21:18 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -261,7 +261,8 @@ nodeTokenType(char *token, int length)
  * lexical tokenizer pg_strtok().  It can read
  * * Value token nodes (integers, floats, or strings);
  * * General nodes (via parseNodeString() from readfuncs.c);
- * * Lists of the above.
+ * * Lists of the above;
+ * * Lists of integers or OIDs.
  * The return value is declared void *, not Node *, to avoid having to
  * cast it explicitly in callers that assign to fields of different types.
  *
@@ -300,14 +301,68 @@ nodeRead(char *token, int tok_len)
            {
                List       *l = NIL;
 
-               for (;;)
+               /*----------
+                * Could be an integer list:    (i int int ...)
+                * or an OID list:              (o int int ...)
+                * or a list of nodes/values:   (node node ...)
+                *----------
+                */
+               token = pg_strtok(&tok_len);
+               if (token == NULL)
+                   elog(ERROR, "unterminated List structure");
+               if (tok_len == 1 && token[0] == 'i')
                {
-                   token = pg_strtok(&tok_len);
-                   if (token == NULL)
-                       elog(ERROR, "unterminated List structure");
-                   if (token[0] == ')')
-                       break;
-                   l = lappend(l, nodeRead(token, tok_len));
+                   /* List of integers */
+                   for (;;)
+                   {
+                       int     val;
+                       char   *endptr;
+
+                       token = pg_strtok(&tok_len);
+                       if (token == NULL)
+                           elog(ERROR, "unterminated List structure");
+                       if (token[0] == ')')
+                           break;
+                       val = (int) strtol(token, &endptr, 10);
+                       if (endptr != token + tok_len)
+                           elog(ERROR, "unrecognized integer: \"%.*s\"",
+                                tok_len, token);
+                       l = lappendi(l, val);
+                   }
+               }
+               else if (tok_len == 1 && token[0] == 'o')
+               {
+                   /* List of OIDs */
+                   for (;;)
+                   {
+                       Oid     val;
+                       char   *endptr;
+
+                       token = pg_strtok(&tok_len);
+                       if (token == NULL)
+                           elog(ERROR, "unterminated List structure");
+                       if (token[0] == ')')
+                           break;
+                       val = (Oid) strtoul(token, &endptr, 10);
+                       if (endptr != token + tok_len)
+                           elog(ERROR, "unrecognized OID: \"%.*s\"",
+                                tok_len, token);
+                       l = lappendo(l, val);
+                   }
+               }
+               else
+               {
+                   /* List of other node types */
+                   for (;;)
+                   {
+                       /* We have already scanned next token... */
+                       if (token[0] == ')')
+                           break;
+                       l = lappend(l, nodeRead(token, tok_len));
+                       token = pg_strtok(&tok_len);
+                       if (token == NULL)
+                           elog(ERROR, "unterminated List structure");
+                   }
                }
                result = (Node *) l;
                break;
index 0e3745997002b59affc277a877b48c607dbceab9..ebd3c636c29db03287b068330eb5dd2e0dc890eb 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.167 2004/05/06 14:01:33 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.168 2004/05/08 21:21:18 tgl Exp $
  *
  * NOTES
  *   Path and Plan nodes do not have any readfuncs support, because we
    token = pg_strtok(&length);     /* skip :fldname */ \
    local_node->fldname = nodeRead(NULL, 0)
 
-/* Read an integer-list field */
+/* Read an integer-list field (XXX combine me with READ_NODE_FIELD) */
 #define READ_INTLIST_FIELD(fldname) \
    token = pg_strtok(&length);     /* skip :fldname */ \
-   local_node->fldname = toIntList(nodeRead(NULL, 0))
+   local_node->fldname = nodeRead(NULL, 0)
 
-/* Read an OID-list field */
+/* Read an OID-list field (XXX combine me with READ_NODE_FIELD) */
 #define READ_OIDLIST_FIELD(fldname) \
    token = pg_strtok(&length);     /* skip :fldname */ \
-   local_node->fldname = toOidList(nodeRead(NULL, 0))
+   local_node->fldname = nodeRead(NULL, 0)
 
 /* Routine exit */
 #define READ_DONE() \
 static Datum readDatum(bool typbyval);
 
 
-/* Convert Value list returned by nodeRead into list of integers */
-static List *
-toIntList(List *list)
-{
-   List       *l;
-
-   foreach(l, list)
-   {
-       Value      *v = (Value *) lfirst(l);
-
-       if (!IsA(v, Integer))
-           elog(ERROR, "unexpected node type: %d", (int) nodeTag(v));
-       lfirsti(l) = intVal(v);
-       pfree(v);
-   }
-   return list;
-}
-
-/* Convert Value list returned by nodeRead into list of OIDs */
-static List *
-toOidList(List *list)
-{
-   List       *l;
-
-   foreach(l, list)
-   {
-       Value      *v = (Value *) lfirst(l);
-
-       /*
-        * This is a bit tricky because OID is unsigned, and so nodeRead
-        * might have concluded the value doesn't fit in an integer. Must
-        * cope with T_Float as well.
-        */
-       if (IsA(v, Integer))
-       {
-           lfirsto(l) = (Oid) intVal(v);
-           pfree(v);
-       }
-       else if (IsA(v, Float))
-       {
-           lfirsto(l) = atooid(strVal(v));
-           pfree(strVal(v));
-           pfree(v);
-       }
-       else
-           elog(ERROR, "unexpected node type: %d", (int) nodeTag(v));
-   }
-   return list;
-}
-
 /*
  * _readQuery
  */
index 3380178a0dd39ec1a7b6f0b74f97d0bda7277cd4..46a8a2d06f30473cdb0c4d28ec94e440d1655030 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.227 2004/05/02 13:39:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.228 2004/05/08 21:21:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 200405020
+#define CATALOG_VERSION_NO 200405081
 
 #endif