Alter string format used for integer and OID lists in stored rules.

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.
This commit is contained in:
Tom Lane 2004-05-08 21:21:18 +00:00
parent 4af3421161
commit c00b309932
5 changed files with 91 additions and 74 deletions

View 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);

View 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 { */

View 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;

View 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
@ -101,15 +101,15 @@
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() \
@ -135,56 +135,6 @@
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
*/

View 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