Skip to content

Commit 2f09dd9

Browse files
author
Thomas G. Lockhart
committed
Fix broken parsing for lists of options. Apparently broken when support was
added for keyword=value options.
1 parent 9af564a commit 2f09dd9

File tree

1 file changed

+59
-57
lines changed

1 file changed

+59
-57
lines changed

src/backend/tcop/variable.c

Lines changed: 59 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
* Routines for handling of 'SET var TO', 'SHOW var' and 'RESET var'
33
* statements.
44
*
5-
* $Id: variable.c,v 1.11 1997/06/03 06:29:31 vadim Exp $
5+
* $Id: variable.c,v 1.12 1997/06/20 17:17:03 thomas Exp $
66
*
77
*/
88

99
#include <stdio.h>
1010
#include <string.h>
11+
#include <ctype.h>
1112
#include "postgres.h"
1213
#include "miscadmin.h"
1314
#include "tcop/variable.h"
@@ -38,78 +39,82 @@ static const char *get_token(char **tok, char **val, const char *str)
3839
{
3940
const char *start;
4041
int len = 0;
41-
42-
*tok = *val = NULL;
43-
42+
43+
*tok = NULL;
44+
if (val != NULL) *val = NULL;
45+
4446
if ( !(*str) )
4547
return NULL;
46-
48+
4749
/* skip white spaces */
48-
while ( *str == ' ' || *str == '\t' )
49-
str++;
50+
while (isspace(*str)) str++;
5051
if ( *str == ',' || *str == '=' )
5152
elog(WARN, "Syntax error near (%s): empty setting", str);
53+
54+
/* end of string? then return NULL */
5255
if ( !(*str) )
5356
return NULL;
54-
57+
58+
/* OK, at beginning of non-NULL string... */
5559
start = str;
56-
60+
5761
/*
5862
* count chars in token until we hit white space or comma
5963
* or '=' or end of string
6064
*/
61-
while ( *str && *str != ' ' && *str != '\t'
62-
&& *str != ',' && *str != '=' )
65+
while ( *str && (! isspace(*str))
66+
&& *str != ',' && *str != '=' )
6367
{
6468
str++;
6569
len++;
6670
}
6771

68-
*tok = (char*) palloc (len + 1);
72+
*tok = (char*) PALLOC(len + 1);
6973
strncpy (*tok, start, len);
7074
(*tok)[len] = '\0';
7175

7276
/* skip white spaces */
73-
while ( *str == ' ' || *str == '\t' )
74-
str++;
75-
76-
if ( !(*str) )
77-
return (NULL);
78-
if ( *str == ',' )
77+
while ( isspace(*str)) str++;
78+
79+
/* end of string? */
80+
if ( !(*str) ) {
81+
return(str);
82+
83+
/* delimiter? */
84+
} else if ( *str == ',' ) {
7985
return (++str);
8086

81-
if ( *str != '=' )
87+
} else if ((val == NULL) || ( *str != '=' )) {
8288
elog(WARN, "Syntax error near (%s)", str);
89+
};
8390

8491
str++; /* '=': get value */
8592
len = 0;
8693

8794
/* skip white spaces */
88-
while ( *str == ' ' || *str == '\t' )
89-
str++;
95+
while ( isspace(*str)) str++;
9096

9197
if ( *str == ',' || !(*str) )
9298
elog(WARN, "Syntax error near (=%s)", str);
9399

94100
start = str;
95101

96102
/*
97-
* count chars in token' value until we hit white space or comma
103+
* count chars in token's value until we hit white space or comma
98104
* or end of string
99105
*/
100-
while ( *str && *str != ' ' && *str != '\t' && *str != ',' )
106+
while ( *str && (! isspace(*str)) && *str != ',' )
101107
{
102108
str++;
103109
len++;
104110
}
105111

106-
*val = (char*) palloc (len + 1);
112+
*val = (char*) PALLOC(len + 1);
107113
strncpy (*val, start, len);
108114
(*val)[len] = '\0';
109115

110116
/* skip white spaces */
111-
while ( *str == ' ' || *str == '\t' )
112-
str++;
117+
while ( isspace(*str)) str++;
113118

114119
if ( !(*str) )
115120
return (NULL);
@@ -120,23 +125,23 @@ static const char *get_token(char **tok, char **val, const char *str)
120125

121126
return str;
122127
}
123-
128+
124129
/*-----------------------------------------------------------------------*/
125130
static bool parse_null(const char *value)
126131
{
127132
return TRUE;
128133
}
129-
134+
130135
static bool show_null(const char *value)
131136
{
132137
return TRUE;
133138
}
134-
139+
135140
static bool reset_null(const char *value)
136141
{
137142
return TRUE;
138143
}
139-
144+
140145
static bool parse_geqo (const char *value)
141146
{
142147
const char *rest;
@@ -146,8 +151,8 @@ static bool parse_geqo (const char *value)
146151
if ( tok == NULL )
147152
elog(WARN, "Value undefined");
148153

149-
if ( rest )
150-
elog(WARN, "Unacceptable data (%s)", rest);
154+
if (( rest ) && ( *rest != '\0' ))
155+
elog(WARN, "Unable to parse '%s'", value);
151156

152157
if ( strcasecmp (tok, "on") == 0 )
153158
{
@@ -158,29 +163,29 @@ static bool parse_geqo (const char *value)
158163
geqo_rels = pg_atoi (val, sizeof(int32), '\0');
159164
if ( geqo_rels <= 1 )
160165
elog(WARN, "Bad value for # of relations (%s)", val);
161-
pfree (val);
166+
PFREE(val);
162167
}
163168
_use_geqo_ = true;
164169
_use_geqo_rels_ = geqo_rels;
165170
}
166171
else if ( strcasecmp (tok, "off") == 0 )
167172
{
168-
if ( val != NULL )
169-
elog(WARN, "Unacceptable data (%s)", val);
173+
if (( val != NULL ) && ( *val != '\0' ))
174+
elog(WARN, "%s does not allow a parameter",tok);
170175
_use_geqo_ = false;
171176
}
172177
else
173178
elog(WARN, "Bad value for GEQO (%s)", value);
174179

175-
pfree (tok);
180+
PFREE(tok);
176181
return TRUE;
177182
}
178183

179184
static bool show_geqo ()
180185
{
181186

182187
if ( _use_geqo_ )
183-
elog (NOTICE, "GEQO is ON begining with %d relations", _use_geqo_rels_);
188+
elog (NOTICE, "GEQO is ON beginning with %d relations", _use_geqo_rels_);
184189
else
185190
elog (NOTICE, "GEQO is OFF");
186191
return TRUE;
@@ -197,7 +202,7 @@ static bool reset_geqo ()
197202
_use_geqo_rels_ = GEQO_RELS;
198203
return TRUE;
199204
}
200-
205+
201206
static bool parse_r_plans (const char *value)
202207
{
203208

@@ -231,7 +236,7 @@ static bool reset_r_plans ()
231236
#endif
232237
return TRUE;
233238
}
234-
239+
235240
static bool parse_cost_heap (const char *value)
236241
{
237242
float32 res = float4in ((char*)value);
@@ -278,16 +283,13 @@ static bool reset_cost_index ()
278283

279284
static bool parse_date(const char *value)
280285
{
281-
char *tok, *val;
286+
char *tok;
282287
int dcnt = 0, ecnt = 0;
283-
284-
while((value = get_token(&tok, &val, value)) != 0)
288+
289+
while((value = get_token(&tok, NULL, value)) != 0)
285290
{
286-
if ( val != NULL )
287-
elog(WARN, "Syntax error near (%s)", val);
288-
289291
/* Ugh. Somebody ought to write a table driven version -- mjl */
290-
292+
291293
if(!strcasecmp(tok, "iso"))
292294
{
293295
DateStyle = USE_ISO_DATES;
@@ -324,15 +326,15 @@ static bool parse_date(const char *value)
324326
{
325327
elog(WARN, "Bad value for date style (%s)", tok);
326328
}
327-
pfree (tok);
329+
PFREE(tok);
328330
}
329-
331+
330332
if(dcnt > 1 || ecnt > 1)
331333
elog(NOTICE, "Conflicting settings for date");
332334

333335
return TRUE;
334336
}
335-
337+
336338
static bool show_date()
337339
{
338340
char buf[64];
@@ -357,15 +359,15 @@ static bool show_date()
357359

358360
return TRUE;
359361
}
360-
362+
361363
static bool reset_date()
362364
{
363365
DateStyle = USE_POSTGRES_DATES;
364366
EuroDates = FALSE;
365367

366368
return TRUE;
367369
}
368-
370+
369371
/*-----------------------------------------------------------------------*/
370372
struct VariableParsers
371373
{
@@ -390,13 +392,13 @@ struct VariableParsers
390392
bool SetPGVariable(const char *name, const char *value)
391393
{
392394
struct VariableParsers *vp;
393-
395+
394396
for(vp = VariableParsers; vp->name; vp++)
395397
{
396398
if(!strcasecmp(vp->name, name))
397399
return (vp->parser)(value);
398400
}
399-
401+
400402
elog(NOTICE, "Unrecognized variable %s", name);
401403

402404
return TRUE;
@@ -406,13 +408,13 @@ bool SetPGVariable(const char *name, const char *value)
406408
bool GetPGVariable(const char *name)
407409
{
408410
struct VariableParsers *vp;
409-
411+
410412
for(vp = VariableParsers; vp->name; vp++)
411413
{
412414
if(!strcasecmp(vp->name, name))
413415
return (vp->show)();
414416
}
415-
417+
416418
elog(NOTICE, "Unrecognized variable %s", name);
417419

418420
return TRUE;
@@ -422,13 +424,13 @@ bool GetPGVariable(const char *name)
422424
bool ResetPGVariable(const char *name)
423425
{
424426
struct VariableParsers *vp;
425-
427+
426428
for(vp = VariableParsers; vp->name; vp++)
427429
{
428430
if(!strcasecmp(vp->name, name))
429431
return (vp->reset)();
430432
}
431-
433+
432434
elog(NOTICE, "Unrecognized variable %s", name);
433435

434436
return TRUE;

0 commit comments

Comments
 (0)