|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * 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 $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
|
51 | 51 | #defineRETURN_NULL(type) do { *isNull = true; return (type) 0; } while (0)
|
52 | 52 |
|
53 | 53 |
|
54 |
| -staticintArrayCount(char*str,int*dim,inttypdelim); |
| 54 | +staticintArrayCount(char*str,int*dim,chartypdelim); |
55 | 55 | staticDatum*ReadArrayStr(char*arrayStr,intnitems,intndim,int*dim,
|
56 | 56 | FmgrInfo*inputproc,Oidtypelem,int32typmod,
|
57 | 57 | chartypdelim,inttyplen,booltypbyval,
|
@@ -245,81 +245,84 @@ array_in(PG_FUNCTION_ARGS)
|
245 | 245 | *-----------------------------------------------------------------------------
|
246 | 246 | */
|
247 | 247 | staticint
|
248 |
| -ArrayCount(char*str,int*dim,inttypdelim) |
| 248 | +ArrayCount(char*str,int*dim,chartypdelim) |
249 | 249 | {
|
250 | 250 | intnest_level=0,
|
251 | 251 | i;
|
252 | 252 | intndim=0,
|
253 | 253 | temp[MAXDIM];
|
254 | 254 | boolscanning_string= false;
|
255 | 255 | booleoArray= false;
|
256 |
| -char*q; |
| 256 | +char*ptr; |
257 | 257 |
|
258 | 258 | for (i=0;i<MAXDIM;++i)
|
259 | 259 | temp[i]=dim[i]=0;
|
260 | 260 |
|
261 | 261 | if (strncmp(str,"{}",2)==0)
|
262 | 262 | return0;
|
263 | 263 |
|
264 |
| -q=str; |
265 |
| -while (eoArray!= true) |
| 264 | +ptr=str; |
| 265 | +while (!eoArray) |
266 | 266 | {
|
267 |
| -booldone= false; |
| 267 | +boolitemdone= false; |
268 | 268 |
|
269 |
| -while (!done) |
| 269 | +while (!itemdone) |
270 | 270 | {
|
271 |
| -switch (*q) |
| 271 | +switch (*ptr) |
272 | 272 | {
|
273 |
| -case'\\': |
274 |
| -/* skip escaped characters (\ and ") inside strings */ |
275 |
| -if (scanning_string&&*(q+1)) |
276 |
| -q++; |
277 |
| -break; |
278 | 273 | 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 */ |
284 | 275 | elog(ERROR,"malformed array constant: %s",str);
|
285 | 276 | 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; |
286 | 284 | case'\"':
|
287 | 285 | scanning_string= !scanning_string;
|
288 | 286 | break;
|
289 | 287 | case'{':
|
290 | 288 | if (!scanning_string)
|
291 | 289 | {
|
| 290 | +if (nest_level >=MAXDIM) |
| 291 | +elog(ERROR,"array_in: illformed array constant"); |
292 | 292 | temp[nest_level]=0;
|
293 | 293 | nest_level++;
|
| 294 | +if (ndim<nest_level) |
| 295 | +ndim=nest_level; |
294 | 296 | }
|
295 | 297 | break;
|
296 | 298 | case'}':
|
297 | 299 | if (!scanning_string)
|
298 | 300 | {
|
299 |
| -if (!ndim) |
300 |
| -ndim=nest_level; |
| 301 | +if (nest_level==0) |
| 302 | +elog(ERROR,"array_in: illformed array constant"); |
301 | 303 | nest_level--;
|
302 |
| -if (nest_level) |
303 |
| -temp[nest_level-1]++; |
304 | 304 | 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 | +} |
306 | 314 | }
|
307 | 315 | break;
|
308 | 316 | 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; |
313 | 319 | break;
|
314 | 320 | }
|
315 |
| -if (!done) |
316 |
| -q++; |
| 321 | +if (!itemdone) |
| 322 | +ptr++; |
317 | 323 | }
|
318 | 324 | temp[ndim-1]++;
|
319 |
| -q++; |
320 |
| -if (!eoArray) |
321 |
| -while (isspace((unsignedchar)*q)) |
322 |
| -q++; |
| 325 | +ptr++; |
323 | 326 | }
|
324 | 327 | for (i=0;i<ndim;++i)
|
325 | 328 | dim[i]=temp[i];
|
@@ -359,103 +362,119 @@ ReadArrayStr(char *arrayStr,
|
359 | 362 | inti,
|
360 | 363 | nest_level=0;
|
361 | 364 | Datum*values;
|
362 |
| -char*p, |
363 |
| -*q, |
364 |
| -*r; |
| 365 | +char*ptr; |
365 | 366 | boolscanning_string= false;
|
| 367 | +booleoArray= false; |
366 | 368 | intindx[MAXDIM],
|
367 | 369 | prod[MAXDIM];
|
368 |
| -booleoArray= false; |
369 | 370 |
|
370 | 371 | mda_get_prod(ndim,dim,prod);
|
371 | 372 | values= (Datum*)palloc(nitems*sizeof(Datum));
|
372 | 373 | MemSet(values,0,nitems*sizeof(Datum));
|
373 | 374 | MemSet(indx,0,sizeof(indx));
|
374 |
| -q=p=arrayStr; |
375 | 375 |
|
376 | 376 | /* read array enclosed within {} */
|
| 377 | +ptr=arrayStr; |
377 | 378 | while (!eoArray)
|
378 | 379 | {
|
379 |
| -booldone= false; |
| 380 | +boolitemdone= false; |
380 | 381 | inti=-1;
|
| 382 | +char*itemstart; |
| 383 | + |
| 384 | +/* skip leading whitespace */ |
| 385 | +while (isspace((unsignedchar)*ptr)) |
| 386 | +ptr++; |
| 387 | +itemstart=ptr; |
381 | 388 |
|
382 |
| -while (!done) |
| 389 | +while (!itemdone) |
383 | 390 | {
|
384 |
| -switch (*q) |
| 391 | +switch (*ptr) |
385 | 392 | {
|
| 393 | +case'\0': |
| 394 | +/* Signal a premature end of the string */ |
| 395 | +elog(ERROR,"malformed array constant: %s",arrayStr); |
| 396 | +break; |
386 | 397 | case'\\':
|
| 398 | +{ |
| 399 | +char*cptr; |
| 400 | + |
387 | 401 | /* 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); |
390 | 406 | break;
|
| 407 | +} |
391 | 408 | 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 | + |
400 | 412 | 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--; |
401 | 418 | break;
|
| 419 | +} |
402 | 420 | case'{':
|
403 | 421 | if (!scanning_string)
|
404 | 422 | {
|
405 |
| -p++; |
406 |
| -nest_level++; |
407 |
| -if (nest_level>ndim) |
| 423 | +if (nest_level >=ndim) |
408 | 424 | elog(ERROR,"array_in: illformed array constant");
|
| 425 | +nest_level++; |
409 | 426 | 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; |
411 | 431 | }
|
412 | 432 | break;
|
413 | 433 | case'}':
|
414 | 434 | if (!scanning_string)
|
415 | 435 | {
|
| 436 | +if (nest_level==0) |
| 437 | +elog(ERROR,"array_in: illformed array constant"); |
416 | 438 | if (i==-1)
|
417 | 439 | i=ArrayGetOffset0(ndim,indx,prod);
|
| 440 | +indx[nest_level-1]=0; |
418 | 441 | nest_level--;
|
419 | 442 | if (nest_level==0)
|
420 |
| -eoArray=done= true; |
| 443 | +eoArray=itemdone= true; |
421 | 444 | else
|
422 | 445 | {
|
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'; |
424 | 454 | indx[nest_level-1]++;
|
425 | 455 | }
|
426 | 456 | }
|
427 | 457 | break;
|
428 | 458 | default:
|
429 |
| -if (*q==typdelim&& !scanning_string) |
| 459 | +if (*ptr==typdelim&& !scanning_string) |
430 | 460 | {
|
431 | 461 | if (i==-1)
|
432 | 462 | i=ArrayGetOffset0(ndim,indx,prod);
|
433 |
| -done= true; |
| 463 | +itemdone= true; |
434 | 464 | indx[ndim-1]++;
|
435 | 465 | }
|
436 | 466 | break;
|
437 | 467 | }
|
438 |
| -if (!done) |
439 |
| -q++; |
| 468 | +if (!itemdone) |
| 469 | +ptr++; |
440 | 470 | }
|
441 |
| -*q='\0'; |
442 |
| -if (i >=nitems) |
| 471 | +*ptr++='\0'; |
| 472 | +if (i<0||i>=nitems) |
443 | 473 | elog(ERROR,"array_in: illformed array constant");
|
444 | 474 | values[i]=FunctionCall3(inputproc,
|
445 |
| -CStringGetDatum(p), |
| 475 | +CStringGetDatum(itemstart), |
446 | 476 | ObjectIdGetDatum(typelem),
|
447 | 477 | 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 |
| -} |
459 | 478 | }
|
460 | 479 |
|
461 | 480 | /*
|
|