Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4057b64

Browse files
committed
Modify readfuncs so that recursive use of stringToNode will not crash
and burn. Just for added luck, change reading of CONST nodes so thatwe do not need to consult pg_type rows while reading them; this meansthat no database access occurs during stringToNode. This requireschanging the order in which const-node fields are written, which meansan initdb is forced.
1 parent1402201 commit4057b64

File tree

5 files changed

+438
-459
lines changed

5 files changed

+438
-459
lines changed

‎src/backend/nodes/outfuncs.c

Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,33 @@
11
/*
2-
*
32
* outfuncs.c
43
* routines to convert a node to ascii representation
54
*
65
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
76
* Portions Copyright (c) 1994, Regents of the University of California
87
*
9-
*$Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.135 2000/12/03 20:45:33 tgl Exp $
8+
*$Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.136 2001/01/07 01:08:47 tgl Exp $
109
*
1110
* NOTES
1211
* Every (plan) node in POSTGRES has an associated "out" routine which
1312
* knows how to create its ascii representation. These functions are
1413
* useful for debugging as well as for storing plans in the system
15-
* catalogs (eg. indexes). This is also the plan string sent out in
16-
* Mariposa.
17-
*
18-
* These functions update the in/out argument of type StringInfo
19-
* passed to them. This argument contains the string holding the ASCII
20-
* representation plus some other information (string length, etc.)
21-
*
14+
* catalogs (eg. views).
2215
*/
2316
#include"postgres.h"
2417

2518
#include<ctype.h>
2619

27-
#include"access/heapam.h"
28-
#include"access/htup.h"
29-
#include"catalog/pg_type.h"
30-
#include"fmgr.h"
3120
#include"lib/stringinfo.h"
32-
#include"nodes/execnodes.h"
3321
#include"nodes/nodes.h"
3422
#include"nodes/parsenodes.h"
35-
#include"nodes/pg_list.h"
3623
#include"nodes/plannodes.h"
3724
#include"nodes/primnodes.h"
3825
#include"nodes/relation.h"
3926
#include"parser/parse.h"
4027
#include"utils/datum.h"
41-
#include"utils/lsyscache.h"
42-
#include"utils/syscache.h"
4328

4429

45-
staticvoid_outDatum(StringInfostr,Datumvalue,Oidtype);
30+
staticvoid_outDatum(StringInfostr,Datumvalue,inttyplen,booltypbyval);
4631
staticvoid_outNode(StringInfostr,void*obj);
4732

4833
/*
@@ -63,8 +48,8 @@ _outToken(StringInfo str, char *s)
6348

6449
/*
6550
* Look for characters or patterns that are treated specially by
66-
* read.c (either inlsptok() or in nodeRead()), and therefore need a
67-
* protective backslash.
51+
* read.c (either inpg_strtok() or in nodeRead()), and therefore need
52+
*aprotective backslash.
6853
*/
6954
/* These characters only need to be quoted at the start of the string */
7055
if (*s=='<'||
@@ -762,18 +747,17 @@ static void
762747
_outConst(StringInfostr,Const*node)
763748
{
764749
appendStringInfo(str,
765-
" CONST :consttype %u :constlen %d :constisnull %s :constvalue ",
750+
" CONST :consttype %u :constlen %d :constbyval %s"
751+
" :constisnull %s :constvalue ",
766752
node->consttype,
767753
node->constlen,
754+
node->constbyval ?"true" :"false",
768755
node->constisnull ?"true" :"false");
769756

770757
if (node->constisnull)
771758
appendStringInfo(str,"<>");
772759
else
773-
_outDatum(str,node->constvalue,node->consttype);
774-
775-
appendStringInfo(str," :constbyval %s ",
776-
node->constbyval ?"true" :"false");
760+
_outDatum(str,node->constvalue,node->constlen,node->constbyval);
777761
}
778762

779763
/*
@@ -1234,38 +1218,31 @@ _outJoinInfo(StringInfo str, JoinInfo *node)
12341218
* Print the value of a Datum given its type.
12351219
*/
12361220
staticvoid
1237-
_outDatum(StringInfostr,Datumvalue,Oidtype)
1221+
_outDatum(StringInfostr,Datumvalue,inttyplen,booltypbyval)
12381222
{
1239-
int16typeLength;
1240-
boolbyValue;
1241-
Sizelength;
1223+
Sizelength,
1224+
i;
12421225
char*s;
1243-
inti;
12441226

1245-
/*
1246-
* find some information about the type and the "real" length of the
1247-
* datum.
1248-
*/
1249-
get_typlenbyval(type,&typeLength,&byValue);
1250-
length=datumGetSize(value,byValue,typeLength);
1227+
length=datumGetSize(value,typbyval,typlen);
12511228

1252-
if (byValue)
1229+
if (typbyval)
12531230
{
12541231
s= (char*) (&value);
12551232
appendStringInfo(str," %u [ ", (unsignedint)length);
1256-
for (i=0;i< (int)sizeof(Datum);i++)
1233+
for (i=0;i< (Size)sizeof(Datum);i++)
12571234
appendStringInfo(str,"%d ", (int) (s[i]));
12581235
appendStringInfo(str,"] ");
12591236
}
12601237
else
1261-
{/* !byValue */
1238+
{
12621239
s= (char*)DatumGetPointer(value);
12631240
if (!PointerIsValid(s))
12641241
appendStringInfo(str," 0 [ ] ");
12651242
else
12661243
{
12671244
appendStringInfo(str," %u [ ", (unsignedint)length);
1268-
for (i=0;i<(int)length;i++)
1245+
for (i=0;i<length;i++)
12691246
appendStringInfo(str,"%d ", (int) (s[i]));
12701247
appendStringInfo(str,"] ");
12711248
}

‎src/backend/nodes/read.c

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.26 2000/12/03 20:45:33 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.27 2001/01/07 01:08:47 tgl Exp $
1313
*
1414
* HISTORY
1515
* AUTHORDATEMAJOR EVENT
@@ -25,17 +25,34 @@
2525
#include"nodes/pg_list.h"
2626
#include"nodes/readfuncs.h"
2727

28+
29+
/* Static state for pg_strtok */
30+
staticchar*pg_strtok_ptr=NULL;
31+
32+
2833
/*
2934
* stringToNode -
3035
* returns a Node with a given legal ASCII representation
3136
*/
3237
void*
3338
stringToNode(char*str)
3439
{
40+
char*save_strtok;
3541
void*retval;
3642

37-
lsptok(str,NULL);/* set the string used in lsptok */
38-
retval=nodeRead(true);/* start reading */
43+
/*
44+
* We save and restore the pre-existing state of pg_strtok.
45+
* This makes the world safe for re-entrant invocation of stringToNode,
46+
* without incurring a lot of notational overhead by having to pass the
47+
* next-character pointer around through all the readfuncs.c code.
48+
*/
49+
save_strtok=pg_strtok_ptr;
50+
51+
pg_strtok_ptr=str;/* point pg_strtok at the string to read */
52+
53+
retval=nodeRead(true);/* do the reading */
54+
55+
pg_strtok_ptr=save_strtok;
3956

4057
returnretval;
4158
}
@@ -47,17 +64,15 @@ stringToNode(char *str)
4764
*****************************************************************************/
4865

4966
/*
50-
*lsptok --- retrieve next "token" from a string.
67+
*pg_strtok --- retrieve next "token" from a string.
5168
*
5269
* Works kinda like strtok, except it never modifies the source string.
5370
* (Instead of storing nulls into the string, the length of the token
5471
* is returned to the caller.)
5572
* Also, the rules about what is a token are hard-wired rather than being
5673
* configured by passing a set of terminating characters.
5774
*
58-
* The string is initially set by passing a non-NULL "string" value,
59-
* and subsequent calls with string==NULL read the previously given value.
60-
* (Pass length==NULL to set the string without reading its first token.)
75+
* The string is assumed to have been initialized already by stringToNode.
6176
*
6277
* The rules for tokens are:
6378
** Whitespace (space, tab, newline) always separates tokens.
@@ -89,28 +104,20 @@ stringToNode(char *str)
89104
* as a single token.
90105
*/
91106
char*
92-
lsptok(char*string,int*length)
107+
pg_strtok(int*length)
93108
{
94-
staticchar*saved_str=NULL;
95109
char*local_str;/* working pointer to string */
96110
char*ret_str;/* start of token to return */
97111

98-
if (string!=NULL)
99-
{
100-
saved_str=string;
101-
if (length==NULL)
102-
returnNULL;
103-
}
104-
105-
local_str=saved_str;
112+
local_str=pg_strtok_ptr;
106113

107114
while (*local_str==' '||*local_str=='\n'||*local_str=='\t')
108115
local_str++;
109116

110117
if (*local_str=='\0')
111118
{
112119
*length=0;
113-
saved_str=local_str;
120+
pg_strtok_ptr=local_str;
114121
returnNULL;/* no more tokens */
115122
}
116123

@@ -147,7 +154,7 @@ lsptok(char *string, int *length)
147154
if (*length==2&&ret_str[0]=='<'&&ret_str[1]=='>')
148155
*length=0;
149156

150-
saved_str=local_str;
157+
pg_strtok_ptr=local_str;
151158

152159
returnret_str;
153160
}
@@ -223,7 +230,7 @@ nodeTokenType(char *token, int length)
223230
}
224231

225232
/*
226-
* these three cases do not need length checks, sincelsptok() will
233+
* these three cases do not need length checks, sincepg_strtok() will
227234
* always treat them as single-byte tokens
228235
*/
229236
elseif (*token=='(')
@@ -248,12 +255,13 @@ nodeTokenType(char *token, int length)
248255
* Slightly higher-level reader.
249256
*
250257
* This routine applies some semantic knowledge on top of the purely
251-
* lexical tokenizerlsptok().It can read
258+
* lexical tokenizerpg_strtok().It can read
252259
** Value token nodes (integers, floats, or strings);
253260
** Plan nodes (via parsePlanString() from readfuncs.c);
254261
** Lists of the above.
255262
*
256-
* Secrets: He assumes that lsptok already has the string (see above).
263+
* We assume pg_strtok is already initialized with a string to read (hence
264+
* this should only be invoked from within a stringToNode operation).
257265
* Any callers should set read_car_only to true.
258266
*/
259267
void*
@@ -266,7 +274,7 @@ nodeRead(bool read_car_only)
266274
*return_value;
267275
boolmake_dotted_pair_cell= false;
268276

269-
token=lsptok(NULL,&tok_len);
277+
token=pg_strtok(&tok_len);
270278

271279
if (token==NULL)
272280
returnNULL;
@@ -277,8 +285,8 @@ nodeRead(bool read_car_only)
277285
{
278286
casePLAN_SYM:
279287
this_value=parsePlanString();
280-
token=lsptok(NULL,&tok_len);
281-
if (token[0]!='}')
288+
token=pg_strtok(&tok_len);
289+
if (token==NULL||token[0]!='}')
282290
elog(ERROR,"nodeRead: did not find '}' at end of plan node");
283291
if (!read_car_only)
284292
make_dotted_pair_cell= true;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp