@@ -1311,12 +1311,11 @@ copy_plpgsql_datums(PLpgSQL_execstate *estate,
1311
1311
1312
1312
case PLPGSQL_DTYPE_ROW :
1313
1313
case PLPGSQL_DTYPE_RECFIELD :
1314
- case PLPGSQL_DTYPE_ARRAYELEM :
1315
1314
1316
1315
/*
1317
1316
* These datum records are read-only at runtime, so no need to
1318
- * copy them (well, RECFIELD and ARRAYELEM contain cached
1319
- * data, but we'd just as soon centralize the caching anyway).
1317
+ * copy them (well, RECFIELD contains cached data, but we'd
1318
+ * just as soon centralize the caching anyway).
1320
1319
*/
1321
1320
outdatum = indatum ;
1322
1321
break ;
@@ -4136,9 +4135,6 @@ plpgsql_estate_setup(PLpgSQL_execstate *estate,
4136
4135
*
4137
4136
* NB: the result of the evaluation is no longer valid after this is done,
4138
4137
* unless it is a pass-by-value datatype.
4139
- *
4140
- * NB: if you change this code, see also the hacks in exec_assign_value's
4141
- * PLPGSQL_DTYPE_ARRAYELEM case for partial cleanup after subscript evals.
4142
4138
* ----------
4143
4139
*/
4144
4140
static void
@@ -5288,198 +5284,6 @@ exec_assign_value(PLpgSQL_execstate *estate,
5288
5284
break ;
5289
5285
}
5290
5286
5291
- case PLPGSQL_DTYPE_ARRAYELEM :
5292
- {
5293
- /*
5294
- * Target is an element of an array
5295
- */
5296
- PLpgSQL_arrayelem * arrayelem ;
5297
- int nsubscripts ;
5298
- int i ;
5299
- PLpgSQL_expr * subscripts [MAXDIM ];
5300
- int subscriptvals [MAXDIM ];
5301
- Datum oldarraydatum ,
5302
- newarraydatum ,
5303
- coerced_value ;
5304
- bool oldarrayisnull ;
5305
- Oid parenttypoid ;
5306
- int32 parenttypmod ;
5307
- SPITupleTable * save_eval_tuptable ;
5308
- MemoryContext oldcontext ;
5309
-
5310
- /*
5311
- * We need to do subscript evaluation, which might require
5312
- * evaluating general expressions; and the caller might have
5313
- * done that too in order to prepare the input Datum. We have
5314
- * to save and restore the caller's SPI_execute result, if
5315
- * any.
5316
- */
5317
- save_eval_tuptable = estate -> eval_tuptable ;
5318
- estate -> eval_tuptable = NULL ;
5319
-
5320
- /*
5321
- * To handle constructs like x[1][2] := something, we have to
5322
- * be prepared to deal with a chain of arrayelem datums. Chase
5323
- * back to find the base array datum, and save the subscript
5324
- * expressions as we go. (We are scanning right to left here,
5325
- * but want to evaluate the subscripts left-to-right to
5326
- * minimize surprises.) Note that arrayelem is left pointing
5327
- * to the leftmost arrayelem datum, where we will cache the
5328
- * array element type data.
5329
- */
5330
- nsubscripts = 0 ;
5331
- do
5332
- {
5333
- arrayelem = (PLpgSQL_arrayelem * ) target ;
5334
- if (nsubscripts >= MAXDIM )
5335
- ereport (ERROR ,
5336
- (errcode (ERRCODE_PROGRAM_LIMIT_EXCEEDED ),
5337
- errmsg ("number of array dimensions (%d) exceeds the maximum allowed (%d)" ,
5338
- nsubscripts + 1 , MAXDIM )));
5339
- subscripts [nsubscripts ++ ] = arrayelem -> subscript ;
5340
- target = estate -> datums [arrayelem -> arrayparentno ];
5341
- } while (target -> dtype == PLPGSQL_DTYPE_ARRAYELEM );
5342
-
5343
- /* Fetch current value of array datum */
5344
- exec_eval_datum (estate , target ,
5345
- & parenttypoid , & parenttypmod ,
5346
- & oldarraydatum , & oldarrayisnull );
5347
-
5348
- /* Update cached type data if necessary */
5349
- if (arrayelem -> parenttypoid != parenttypoid ||
5350
- arrayelem -> parenttypmod != parenttypmod )
5351
- {
5352
- Oid arraytypoid ;
5353
- int32 arraytypmod = parenttypmod ;
5354
- int16 arraytyplen ;
5355
- Oid elemtypoid ;
5356
- int16 elemtyplen ;
5357
- bool elemtypbyval ;
5358
- char elemtypalign ;
5359
-
5360
- /* If target is domain over array, reduce to base type */
5361
- arraytypoid = getBaseTypeAndTypmod (parenttypoid ,
5362
- & arraytypmod );
5363
-
5364
- /* ... and identify the element type */
5365
- elemtypoid = get_element_type (arraytypoid );
5366
- if (!OidIsValid (elemtypoid ))
5367
- ereport (ERROR ,
5368
- (errcode (ERRCODE_DATATYPE_MISMATCH ),
5369
- errmsg ("subscripted object is not an array" )));
5370
-
5371
- /* Collect needed data about the types */
5372
- arraytyplen = get_typlen (arraytypoid );
5373
-
5374
- get_typlenbyvalalign (elemtypoid ,
5375
- & elemtyplen ,
5376
- & elemtypbyval ,
5377
- & elemtypalign );
5378
-
5379
- /* Now safe to update the cached data */
5380
- arrayelem -> parenttypoid = parenttypoid ;
5381
- arrayelem -> parenttypmod = parenttypmod ;
5382
- arrayelem -> arraytypoid = arraytypoid ;
5383
- arrayelem -> arraytypmod = arraytypmod ;
5384
- arrayelem -> arraytyplen = arraytyplen ;
5385
- arrayelem -> elemtypoid = elemtypoid ;
5386
- arrayelem -> elemtyplen = elemtyplen ;
5387
- arrayelem -> elemtypbyval = elemtypbyval ;
5388
- arrayelem -> elemtypalign = elemtypalign ;
5389
- }
5390
-
5391
- /*
5392
- * Evaluate the subscripts, switch into left-to-right order.
5393
- * Like the expression built by ExecInitSubscriptingRef(),
5394
- * complain if any subscript is null.
5395
- */
5396
- for (i = 0 ; i < nsubscripts ; i ++ )
5397
- {
5398
- bool subisnull ;
5399
-
5400
- subscriptvals [i ] =
5401
- exec_eval_integer (estate ,
5402
- subscripts [nsubscripts - 1 - i ],
5403
- & subisnull );
5404
- if (subisnull )
5405
- ereport (ERROR ,
5406
- (errcode (ERRCODE_NULL_VALUE_NOT_ALLOWED ),
5407
- errmsg ("array subscript in assignment must not be null" )));
5408
-
5409
- /*
5410
- * Clean up in case the subscript expression wasn't
5411
- * simple. We can't do exec_eval_cleanup, but we can do
5412
- * this much (which is safe because the integer subscript
5413
- * value is surely pass-by-value), and we must do it in
5414
- * case the next subscript expression isn't simple either.
5415
- */
5416
- if (estate -> eval_tuptable != NULL )
5417
- SPI_freetuptable (estate -> eval_tuptable );
5418
- estate -> eval_tuptable = NULL ;
5419
- }
5420
-
5421
- /* Now we can restore caller's SPI_execute result if any. */
5422
- Assert (estate -> eval_tuptable == NULL );
5423
- estate -> eval_tuptable = save_eval_tuptable ;
5424
-
5425
- /* Coerce source value to match array element type. */
5426
- coerced_value = exec_cast_value (estate ,
5427
- value ,
5428
- & isNull ,
5429
- valtype ,
5430
- valtypmod ,
5431
- arrayelem -> elemtypoid ,
5432
- arrayelem -> arraytypmod );
5433
-
5434
- /*
5435
- * If the original array is null, cons up an empty array so
5436
- * that the assignment can proceed; we'll end with a
5437
- * one-element array containing just the assigned-to
5438
- * subscript. This only works for varlena arrays, though; for
5439
- * fixed-length array types we skip the assignment. We can't
5440
- * support assignment of a null entry into a fixed-length
5441
- * array, either, so that's a no-op too. This is all ugly but
5442
- * corresponds to the current behavior of execExpr*.c.
5443
- */
5444
- if (arrayelem -> arraytyplen > 0 && /* fixed-length array? */
5445
- (oldarrayisnull || isNull ))
5446
- return ;
5447
-
5448
- /* empty array, if any, and newarraydatum are short-lived */
5449
- oldcontext = MemoryContextSwitchTo (get_eval_mcontext (estate ));
5450
-
5451
- if (oldarrayisnull )
5452
- oldarraydatum = PointerGetDatum (construct_empty_array (arrayelem -> elemtypoid ));
5453
-
5454
- /*
5455
- * Build the modified array value.
5456
- */
5457
- newarraydatum = array_set_element (oldarraydatum ,
5458
- nsubscripts ,
5459
- subscriptvals ,
5460
- coerced_value ,
5461
- isNull ,
5462
- arrayelem -> arraytyplen ,
5463
- arrayelem -> elemtyplen ,
5464
- arrayelem -> elemtypbyval ,
5465
- arrayelem -> elemtypalign );
5466
-
5467
- MemoryContextSwitchTo (oldcontext );
5468
-
5469
- /*
5470
- * Assign the new array to the base variable. It's never NULL
5471
- * at this point. Note that if the target is a domain,
5472
- * coercing the base array type back up to the domain will
5473
- * happen within exec_assign_value.
5474
- */
5475
- exec_assign_value (estate , target ,
5476
- newarraydatum ,
5477
- false,
5478
- arrayelem -> arraytypoid ,
5479
- arrayelem -> arraytypmod );
5480
- break ;
5481
- }
5482
-
5483
5287
default :
5484
5288
elog (ERROR , "unrecognized dtype: %d" , target -> dtype );
5485
5289
}
@@ -5490,8 +5294,8 @@ exec_assign_value(PLpgSQL_execstate *estate,
5490
5294
*
5491
5295
* The type oid, typmod, value in Datum format, and null flag are returned.
5492
5296
*
5493
- * At present this doesn't handle PLpgSQL_expr or PLpgSQL_arrayelem datums;
5494
- * that's not needed because we never pass references to such datums to SPI.
5297
+ * At present this doesn't handle PLpgSQL_expr datums; that's not needed
5298
+ * because we never pass references to such datums to SPI.
5495
5299
*
5496
5300
* NOTE: the returned Datum points right at the stored value in the case of
5497
5301
* pass-by-reference datatypes. Generally callers should take care not to
0 commit comments