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

Commit0f2fbbb

Browse files
committed
Try to make array_in's behavior a tad less bizarre. Leading whitespace
before a data item is now always skipped, rather than only sometimes.Backslashes not within double-quoted text are treated reasonably, asare multiple sequences of quoted text in a single data item. But itstill seems rather prone to misbehavior if the input is not completelysyntactically correct --- in particular, garbage following a right bracewill be ignored.
1 parent134fe5e commit0f2fbbb

File tree

1 file changed

+95
-76
lines changed

1 file changed

+95
-76
lines changed

‎src/backend/utils/adt/arrayfuncs.c

Lines changed: 95 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.75 2002/03/02 00:34:24 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.76 2002/03/16 22:47:13 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -51,7 +51,7 @@
5151
#defineRETURN_NULL(type) do { *isNull = true; return (type) 0; } while (0)
5252

5353

54-
staticintArrayCount(char*str,int*dim,inttypdelim);
54+
staticintArrayCount(char*str,int*dim,chartypdelim);
5555
staticDatum*ReadArrayStr(char*arrayStr,intnitems,intndim,int*dim,
5656
FmgrInfo*inputproc,Oidtypelem,int32typmod,
5757
chartypdelim,inttyplen,booltypbyval,
@@ -245,81 +245,84 @@ array_in(PG_FUNCTION_ARGS)
245245
*-----------------------------------------------------------------------------
246246
*/
247247
staticint
248-
ArrayCount(char*str,int*dim,inttypdelim)
248+
ArrayCount(char*str,int*dim,chartypdelim)
249249
{
250250
intnest_level=0,
251251
i;
252252
intndim=0,
253253
temp[MAXDIM];
254254
boolscanning_string= false;
255255
booleoArray= false;
256-
char*q;
256+
char*ptr;
257257

258258
for (i=0;i<MAXDIM;++i)
259259
temp[i]=dim[i]=0;
260260

261261
if (strncmp(str,"{}",2)==0)
262262
return0;
263263

264-
q=str;
265-
while (eoArray!= true)
264+
ptr=str;
265+
while (!eoArray)
266266
{
267-
booldone= false;
267+
boolitemdone= false;
268268

269-
while (!done)
269+
while (!itemdone)
270270
{
271-
switch (*q)
271+
switch (*ptr)
272272
{
273-
case'\\':
274-
/* skip escaped characters (\ and ") inside strings */
275-
if (scanning_string&&*(q+1))
276-
q++;
277-
break;
278273
case'\0':
279-
280-
/*
281-
* Signal a premature end of the string. DZ -
282-
* 2-9-1996
283-
*/
274+
/* Signal a premature end of the string */
284275
elog(ERROR,"malformed array constant: %s",str);
285276
break;
277+
case'\\':
278+
/* skip the escaped character */
279+
if (*(ptr+1))
280+
ptr++;
281+
else
282+
elog(ERROR,"malformed array constant: %s",str);
283+
break;
286284
case'\"':
287285
scanning_string= !scanning_string;
288286
break;
289287
case'{':
290288
if (!scanning_string)
291289
{
290+
if (nest_level >=MAXDIM)
291+
elog(ERROR,"array_in: illformed array constant");
292292
temp[nest_level]=0;
293293
nest_level++;
294+
if (ndim<nest_level)
295+
ndim=nest_level;
294296
}
295297
break;
296298
case'}':
297299
if (!scanning_string)
298300
{
299-
if (!ndim)
300-
ndim=nest_level;
301+
if (nest_level==0)
302+
elog(ERROR,"array_in: illformed array constant");
301303
nest_level--;
302-
if (nest_level)
303-
temp[nest_level-1]++;
304304
if (nest_level==0)
305-
eoArray=done= true;
305+
eoArray=itemdone= true;
306+
else
307+
{
308+
/*
309+
* We don't set itemdone here; see comments in
310+
* ReadArrayStr
311+
*/
312+
temp[nest_level-1]++;
313+
}
306314
}
307315
break;
308316
default:
309-
if (!ndim)
310-
ndim=nest_level;
311-
if (*q==typdelim&& !scanning_string)
312-
done= true;
317+
if (*ptr==typdelim&& !scanning_string)
318+
itemdone= true;
313319
break;
314320
}
315-
if (!done)
316-
q++;
321+
if (!itemdone)
322+
ptr++;
317323
}
318324
temp[ndim-1]++;
319-
q++;
320-
if (!eoArray)
321-
while (isspace((unsignedchar)*q))
322-
q++;
325+
ptr++;
323326
}
324327
for (i=0;i<ndim;++i)
325328
dim[i]=temp[i];
@@ -359,103 +362,119 @@ ReadArrayStr(char *arrayStr,
359362
inti,
360363
nest_level=0;
361364
Datum*values;
362-
char*p,
363-
*q,
364-
*r;
365+
char*ptr;
365366
boolscanning_string= false;
367+
booleoArray= false;
366368
intindx[MAXDIM],
367369
prod[MAXDIM];
368-
booleoArray= false;
369370

370371
mda_get_prod(ndim,dim,prod);
371372
values= (Datum*)palloc(nitems*sizeof(Datum));
372373
MemSet(values,0,nitems*sizeof(Datum));
373374
MemSet(indx,0,sizeof(indx));
374-
q=p=arrayStr;
375375

376376
/* read array enclosed within {} */
377+
ptr=arrayStr;
377378
while (!eoArray)
378379
{
379-
booldone= false;
380+
boolitemdone= false;
380381
inti=-1;
382+
char*itemstart;
383+
384+
/* skip leading whitespace */
385+
while (isspace((unsignedchar)*ptr))
386+
ptr++;
387+
itemstart=ptr;
381388

382-
while (!done)
389+
while (!itemdone)
383390
{
384-
switch (*q)
391+
switch (*ptr)
385392
{
393+
case'\0':
394+
/* Signal a premature end of the string */
395+
elog(ERROR,"malformed array constant: %s",arrayStr);
396+
break;
386397
case'\\':
398+
{
399+
char*cptr;
400+
387401
/* Crunch the string on top of the backslash. */
388-
for (r=q;*r!='\0';r++)
389-
*r=*(r+1);
402+
for (cptr=ptr;*cptr!='\0';cptr++)
403+
*cptr=*(cptr+1);
404+
if (*ptr=='\0')
405+
elog(ERROR,"malformed array constant: %s",arrayStr);
390406
break;
407+
}
391408
case'\"':
392-
if (!scanning_string)
393-
{
394-
while (p!=q)
395-
p++;
396-
p++;/* get p past first doublequote */
397-
}
398-
else
399-
*q='\0';
409+
{
410+
char*cptr;
411+
400412
scanning_string= !scanning_string;
413+
/* Crunch the string on top of the quote. */
414+
for (cptr=ptr;*cptr!='\0';cptr++)
415+
*cptr=*(cptr+1);
416+
/* Back up to not miss following character. */
417+
ptr--;
401418
break;
419+
}
402420
case'{':
403421
if (!scanning_string)
404422
{
405-
p++;
406-
nest_level++;
407-
if (nest_level>ndim)
423+
if (nest_level >=ndim)
408424
elog(ERROR,"array_in: illformed array constant");
425+
nest_level++;
409426
indx[nest_level-1]=0;
410-
indx[ndim-1]=0;
427+
/* skip leading whitespace */
428+
while (isspace((unsignedchar)*(ptr+1)))
429+
ptr++;
430+
itemstart=ptr+1;
411431
}
412432
break;
413433
case'}':
414434
if (!scanning_string)
415435
{
436+
if (nest_level==0)
437+
elog(ERROR,"array_in: illformed array constant");
416438
if (i==-1)
417439
i=ArrayGetOffset0(ndim,indx,prod);
440+
indx[nest_level-1]=0;
418441
nest_level--;
419442
if (nest_level==0)
420-
eoArray=done= true;
443+
eoArray=itemdone= true;
421444
else
422445
{
423-
*q='\0';
446+
/*
447+
* tricky coding: terminate item value string at
448+
* first '}', but don't process it till we see
449+
* a typdelim char or end of array. This handles
450+
* case where several '}'s appear successively
451+
* in a multidimensional array.
452+
*/
453+
*ptr='\0';
424454
indx[nest_level-1]++;
425455
}
426456
}
427457
break;
428458
default:
429-
if (*q==typdelim&& !scanning_string)
459+
if (*ptr==typdelim&& !scanning_string)
430460
{
431461
if (i==-1)
432462
i=ArrayGetOffset0(ndim,indx,prod);
433-
done= true;
463+
itemdone= true;
434464
indx[ndim-1]++;
435465
}
436466
break;
437467
}
438-
if (!done)
439-
q++;
468+
if (!itemdone)
469+
ptr++;
440470
}
441-
*q='\0';
442-
if (i >=nitems)
471+
*ptr++='\0';
472+
if (i<0||i>=nitems)
443473
elog(ERROR,"array_in: illformed array constant");
444474
values[i]=FunctionCall3(inputproc,
445-
CStringGetDatum(p),
475+
CStringGetDatum(itemstart),
446476
ObjectIdGetDatum(typelem),
447477
Int32GetDatum(typmod));
448-
p=++q;
449-
450-
/*
451-
* if not at the end of the array skip white space
452-
*/
453-
if (!eoArray)
454-
while (isspace((unsignedchar)*q))
455-
{
456-
p++;
457-
q++;
458-
}
459478
}
460479

461480
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp