Skip to content

Commit eee6f9d

Browse files
committed
Rewrite nodeRead() in a less obfuscated fashion, per discussion with
Neil Conway.
1 parent 839be02 commit eee6f9d

File tree

4 files changed

+56
-84
lines changed

4 files changed

+56
-84
lines changed

src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.233 2004/03/17 20:48:42 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.234 2004/05/06 14:01:33 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -130,7 +130,6 @@ _outToken(StringInfo str, char *s)
130130
/* These characters only need to be quoted at the start of the string */
131131
if (*s == '<' ||
132132
*s == '\"' ||
133-
*s == '@' ||
134133
isdigit((unsigned char) *s) ||
135134
((*s == '+' || *s == '-') &&
136135
(isdigit((unsigned char) s[1]) || s[1] == '.')))

src/backend/nodes/read.c

Lines changed: 49 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/nodes/read.c,v 1.39 2004/01/09 03:07:32 momjian Exp $
12+
* $PostgreSQL: pgsql/src/backend/nodes/read.c,v 1.40 2004/05/06 14:01:33 tgl Exp $
1313
*
1414
* HISTORY
1515
* AUTHOR DATE MAJOR EVENT
@@ -20,7 +20,6 @@
2020
#include "postgres.h"
2121

2222
#include <ctype.h>
23-
#include <errno.h>
2423

2524
#include "nodes/pg_list.h"
2625
#include "nodes/readfuncs.h"
@@ -51,7 +50,7 @@ stringToNode(char *str)
5150

5251
pg_strtok_ptr = str; /* point pg_strtok at the string to read */
5352

54-
retval = nodeRead(true); /* do the reading */
53+
retval = nodeRead(NULL, 0); /* do the reading */
5554

5655
pg_strtok_ptr = save_strtok;
5756

@@ -184,17 +183,16 @@ debackslash(char *token, int length)
184183

185184
#define RIGHT_PAREN (1000000 + 1)
186185
#define LEFT_PAREN (1000000 + 2)
187-
#define NODE_SYM (1000000 + 3)
188-
#define AT_SYMBOL (1000000 + 4)
189-
#define ATOM_TOKEN (1000000 + 5)
186+
#define LEFT_BRACE (1000000 + 3)
187+
#define OTHER_TOKEN (1000000 + 4)
190188

191189
/*
192190
* nodeTokenType -
193191
* returns the type of the node token contained in token.
194192
* It returns one of the following valid NodeTags:
195193
* T_Integer, T_Float, T_String, T_BitString
196194
* and some of its own:
197-
* RIGHT_PAREN, LEFT_PAREN, NODE_SYM, AT_SYMBOL, ATOM_TOKEN
195+
* RIGHT_PAREN, LEFT_PAREN, LEFT_BRACE, OTHER_TOKEN
198196
*
199197
* Assumption: the ascii representation is legal
200198
*/
@@ -245,15 +243,13 @@ nodeTokenType(char *token, int length)
245243
else if (*token == ')')
246244
retval = RIGHT_PAREN;
247245
else if (*token == '{')
248-
retval = NODE_SYM;
249-
else if (*token == '@' && length == 1)
250-
retval = AT_SYMBOL;
246+
retval = LEFT_BRACE;
251247
else if (*token == '\"' && length > 1 && token[length - 1] == '\"')
252248
retval = T_String;
253249
else if (*token == 'b')
254250
retval = T_BitString;
255251
else
256-
retval = ATOM_TOKEN;
252+
retval = OTHER_TOKEN;
257253
return retval;
258254
}
259255

@@ -266,77 +262,70 @@ nodeTokenType(char *token, int length)
266262
* * Value token nodes (integers, floats, or strings);
267263
* * General nodes (via parseNodeString() from readfuncs.c);
268264
* * Lists of the above.
265+
* The return value is declared void *, not Node *, to avoid having to
266+
* cast it explicitly in callers that assign to fields of different types.
267+
*
268+
* External callers should always pass NULL/0 for the arguments. Internally
269+
* a non-NULL token may be passed when the upper recursion level has already
270+
* scanned the first token of a node's representation.
269271
*
270272
* We assume pg_strtok is already initialized with a string to read (hence
271273
* this should only be invoked from within a stringToNode operation).
272-
* Any callers should set read_car_only to true.
273274
*/
274275
void *
275-
nodeRead(bool read_car_only)
276+
nodeRead(char *token, int tok_len)
276277
{
277-
char *token;
278-
int tok_len;
278+
Node *result;
279279
NodeTag type;
280-
Node *this_value,
281-
*return_value;
282-
bool make_dotted_pair_cell = false;
283280

284-
token = pg_strtok(&tok_len);
281+
if (token == NULL) /* need to read a token? */
282+
{
283+
token = pg_strtok(&tok_len);
285284

286-
if (token == NULL)
287-
return NULL;
285+
if (token == NULL) /* end of input */
286+
return NULL;
287+
}
288288

289289
type = nodeTokenType(token, tok_len);
290290

291291
switch (type)
292292
{
293-
case NODE_SYM:
294-
this_value = parseNodeString();
293+
case LEFT_BRACE:
294+
result = parseNodeString();
295295
token = pg_strtok(&tok_len);
296296
if (token == NULL || token[0] != '}')
297297
elog(ERROR, "did not find '}' at end of input node");
298-
if (!read_car_only)
299-
make_dotted_pair_cell = true;
300-
else
301-
make_dotted_pair_cell = false;
302298
break;
303299
case LEFT_PAREN:
304-
if (!read_car_only)
305300
{
306-
List *l = makeNode(List);
307-
308-
lfirst(l) = nodeRead(false);
309-
lnext(l) = nodeRead(false);
310-
this_value = (Node *) l;
301+
List *l = NIL;
302+
303+
for (;;)
304+
{
305+
token = pg_strtok(&tok_len);
306+
if (token == NULL)
307+
elog(ERROR, "unterminated List structure");
308+
if (token[0] == ')')
309+
break;
310+
l = lappend(l, nodeRead(token, tok_len));
311+
}
312+
result = (Node *) l;
313+
break;
311314
}
312-
else
313-
this_value = nodeRead(false);
314-
break;
315315
case RIGHT_PAREN:
316-
this_value = NULL;
317-
break;
318-
case AT_SYMBOL:
319-
this_value = NULL;
316+
elog(ERROR, "unexpected right parenthesis");
317+
result = NULL; /* keep compiler happy */
320318
break;
321-
case ATOM_TOKEN:
319+
case OTHER_TOKEN:
322320
if (tok_len == 0)
323321
{
324-
/* must be "<>" */
325-
this_value = NULL;
326-
327-
/*
328-
* It might be NULL but it is an atom!
329-
*/
330-
if (read_car_only)
331-
make_dotted_pair_cell = false;
332-
else
333-
make_dotted_pair_cell = true;
322+
/* must be "<>" --- represents a null pointer */
323+
result = NULL;
334324
}
335325
else
336326
{
337-
/* !attention! result is not a Node. Use with caution. */
338-
this_value = (Node *) debackslash(token, tok_len);
339-
make_dotted_pair_cell = true;
327+
elog(ERROR, "unrecognized token: \"%.*s\"", tok_len, token);
328+
result = NULL; /* keep compiler happy */
340329
}
341330
break;
342331
case T_Integer:
@@ -345,23 +334,20 @@ nodeRead(bool read_car_only)
345334
* we know that the token terminates on a char atol will stop
346335
* at
347336
*/
348-
this_value = (Node *) makeInteger(atol(token));
349-
make_dotted_pair_cell = true;
337+
result = (Node *) makeInteger(atol(token));
350338
break;
351339
case T_Float:
352340
{
353341
char *fval = (char *) palloc(tok_len + 1);
354342

355343
memcpy(fval, token, tok_len);
356344
fval[tok_len] = '\0';
357-
this_value = (Node *) makeFloat(fval);
358-
make_dotted_pair_cell = true;
345+
result = (Node *) makeFloat(fval);
359346
}
360347
break;
361348
case T_String:
362349
/* need to remove leading and trailing quotes, and backslashes */
363-
this_value = (Node *) makeString(debackslash(token + 1, tok_len - 2));
364-
make_dotted_pair_cell = true;
350+
result = (Node *) makeString(debackslash(token + 1, tok_len - 2));
365351
break;
366352
case T_BitString:
367353
{
@@ -370,27 +356,14 @@ nodeRead(bool read_car_only)
370356
/* skip leading 'b' */
371357
strncpy(val, token + 1, tok_len - 1);
372358
val[tok_len - 1] = '\0';
373-
this_value = (Node *) makeBitString(val);
359+
result = (Node *) makeBitString(val);
374360
break;
375361
}
376362
default:
377363
elog(ERROR, "unrecognized node type: %d", (int) type);
378-
this_value = NULL; /* keep compiler happy */
364+
result = NULL; /* keep compiler happy */
379365
break;
380366
}
381-
if (make_dotted_pair_cell)
382-
{
383-
List *l = makeNode(List);
384367

385-
lfirst(l) = this_value;
386-
387-
if (!read_car_only)
388-
lnext(l) = nodeRead(false);
389-
else
390-
lnext(l) = NULL;
391-
return_value = (Node *) l;
392-
}
393-
else
394-
return_value = this_value;
395-
return return_value;
368+
return (void *) result;
396369
}

src/backend/nodes/readfuncs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.166 2004/03/17 20:48:42 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.167 2004/05/06 14:01:33 tgl Exp $
1212
*
1313
* NOTES
1414
* Path and Plan nodes do not have any readfuncs support, because we
@@ -99,17 +99,17 @@
9999
/* Read a Node field */
100100
#define READ_NODE_FIELD(fldname) \
101101
token = pg_strtok(&length); /* skip :fldname */ \
102-
local_node->fldname = nodeRead(true)
102+
local_node->fldname = nodeRead(NULL, 0)
103103

104104
/* Read an integer-list field */
105105
#define READ_INTLIST_FIELD(fldname) \
106106
token = pg_strtok(&length); /* skip :fldname */ \
107-
local_node->fldname = toIntList(nodeRead(true))
107+
local_node->fldname = toIntList(nodeRead(NULL, 0))
108108

109109
/* Read an OID-list field */
110110
#define READ_OIDLIST_FIELD(fldname) \
111111
token = pg_strtok(&length); /* skip :fldname */ \
112-
local_node->fldname = toOidList(nodeRead(true))
112+
local_node->fldname = toOidList(nodeRead(NULL, 0))
113113

114114
/* Routine exit */
115115
#define READ_DONE() \

src/include/nodes/readfuncs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/nodes/readfuncs.h,v 1.18 2003/11/29 22:41:06 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/include/nodes/readfuncs.h,v 1.19 2004/05/06 14:01:33 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -21,7 +21,7 @@
2121
*/
2222
extern char *pg_strtok(int *length);
2323
extern char *debackslash(char *token, int length);
24-
extern void *nodeRead(bool read_car_only);
24+
extern void *nodeRead(char *token, int tok_len);
2525

2626
/*
2727
* prototypes for functions in readfuncs.c

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy