OSDN Git Service

Alter string format used for integer and OID lists in stored rules.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 8 May 2004 21:21:18 +0000 (21:21 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
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 788e7dc..9139a9b 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 074a838..14f73b1 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 402c999..e90b413 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 0e37459..ebd3c63 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 3380178..46a8a2d 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