Commit c00b3099 authored by Tom Lane's avatar Tom Lane

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.
parent 4af34211
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* Every node type that can appear in stored rules' parsetrees *must* * Every node type that can appear in stored rules' parsetrees *must*
...@@ -155,6 +155,7 @@ _outIntList(StringInfo str, List *list) ...@@ -155,6 +155,7 @@ _outIntList(StringInfo str, List *list)
List *l; List *l;
appendStringInfoChar(str, '('); appendStringInfoChar(str, '(');
appendStringInfoChar(str, 'i');
foreach(l, list) foreach(l, list)
appendStringInfo(str, " %d", lfirsti(l)); appendStringInfo(str, " %d", lfirsti(l));
appendStringInfoChar(str, ')'); appendStringInfoChar(str, ')');
...@@ -170,6 +171,7 @@ _outOidList(StringInfo str, List *list) ...@@ -170,6 +171,7 @@ _outOidList(StringInfo str, List *list)
List *l; List *l;
appendStringInfoChar(str, '('); appendStringInfoChar(str, '(');
appendStringInfoChar(str, 'o');
foreach(l, list) foreach(l, list)
appendStringInfo(str, " %u", lfirsto(l)); appendStringInfo(str, " %u", lfirsto(l));
appendStringInfoChar(str, ')'); appendStringInfoChar(str, ')');
...@@ -179,8 +181,9 @@ _outOidList(StringInfo str, List *list) ...@@ -179,8 +181,9 @@ _outOidList(StringInfo str, List *list)
* _outBitmapset - * _outBitmapset -
* converts a bitmap set of integers * converts a bitmap set of integers
* *
* Note: for historical reasons, the output is formatted exactly like * Note: the output format is "(b int int ...)", similar to an integer List.
* an integer List would be. * 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 static void
_outBitmapset(StringInfo str, Bitmapset *bms) _outBitmapset(StringInfo str, Bitmapset *bms)
...@@ -189,6 +192,7 @@ _outBitmapset(StringInfo str, Bitmapset *bms) ...@@ -189,6 +192,7 @@ _outBitmapset(StringInfo str, Bitmapset *bms)
int x; int x;
appendStringInfoChar(str, '('); appendStringInfoChar(str, '(');
appendStringInfoChar(str, 'b');
tmpset = bms_copy(bms); tmpset = bms_copy(bms);
while ((x = bms_first_member(tmpset)) >= 0) while ((x = bms_first_member(tmpset)) >= 0)
appendStringInfo(str, " %d", x); appendStringInfo(str, " %d", x);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -194,12 +194,20 @@ pretty_format_node_dump(const char *dump) ...@@ -194,12 +194,20 @@ pretty_format_node_dump(const char *dump)
} }
j = indentDist - 1; j = indentDist - 1;
/* j will equal indentDist on next loop iteration */ /* j will equal indentDist on next loop iteration */
/* suppress whitespace just after } */
while (dump[i+1] == ' ')
i++;
break; break;
case ')': case ')':
/* force line break after ')' */ /* force line break after ), unless another ) follows */
if (dump[i+1] != ')')
{
line[j + 1] = '\0'; line[j + 1] = '\0';
appendStringInfo(&str, "%s\n", line); appendStringInfo(&str, "%s\n", line);
j = indentDist - 1; j = indentDist - 1;
while (dump[i+1] == ' ')
i++;
}
break; break;
case '{': case '{':
/* force line break before { */ /* force line break before { */
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -261,7 +261,8 @@ nodeTokenType(char *token, int length) ...@@ -261,7 +261,8 @@ nodeTokenType(char *token, int length)
* lexical tokenizer pg_strtok(). It can read * lexical tokenizer pg_strtok(). It can read
* * Value token nodes (integers, floats, or strings); * * Value token nodes (integers, floats, or strings);
* * General nodes (via parseNodeString() from readfuncs.c); * * 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 * The return value is declared void *, not Node *, to avoid having to
* cast it explicitly in callers that assign to fields of different types. * cast it explicitly in callers that assign to fields of different types.
* *
...@@ -300,14 +301,68 @@ nodeRead(char *token, int tok_len) ...@@ -300,14 +301,68 @@ nodeRead(char *token, int tok_len)
{ {
List *l = NIL; List *l = NIL;
/*----------
* 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')
{
/* List of integers */
for (;;) for (;;)
{ {
int val;
char *endptr;
token = pg_strtok(&tok_len); token = pg_strtok(&tok_len);
if (token == NULL) if (token == NULL)
elog(ERROR, "unterminated List structure"); 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] == ')') if (token[0] == ')')
break; break;
l = lappend(l, nodeRead(token, tok_len)); l = lappend(l, nodeRead(token, tok_len));
token = pg_strtok(&tok_len);
if (token == NULL)
elog(ERROR, "unterminated List structure");
}
} }
result = (Node *) l; result = (Node *) l;
break; break;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* Path and Plan nodes do not have any readfuncs support, because we * Path and Plan nodes do not have any readfuncs support, because we
...@@ -101,15 +101,15 @@ ...@@ -101,15 +101,15 @@
token = pg_strtok(&length); /* skip :fldname */ \ token = pg_strtok(&length); /* skip :fldname */ \
local_node->fldname = nodeRead(NULL, 0) 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) \ #define READ_INTLIST_FIELD(fldname) \
token = pg_strtok(&length); /* skip :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) \ #define READ_OIDLIST_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \ token = pg_strtok(&length); /* skip :fldname */ \
local_node->fldname = toOidList(nodeRead(NULL, 0)) local_node->fldname = nodeRead(NULL, 0)
/* Routine exit */ /* Routine exit */
#define READ_DONE() \ #define READ_DONE() \
...@@ -135,56 +135,6 @@ ...@@ -135,56 +135,6 @@
static Datum readDatum(bool typbyval); 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 * _readQuery
*/ */
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200405020 #define CATALOG_VERSION_NO 200405081
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment