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

Commite983c4d

Browse files
committed
Rationalize the APIs of array element/slice access functions.
The four functions array_ref, array_set, array_get_slice, array_set_slicehave traditionally declared their array inputs and results as being of type"ArrayType *". This is a lie, and has been since Berkeley days, becausethey actually also support "fixed-length array" types such as "name" and"point"; not to mention that the inputs could be toasted. These valuesshould be declared Datum instead to avoid confusion. The current codingalready risks possible misoptimization by compilers, and it'll get worsewhen "expanded" array representations become a valid alternative.However, there's a fair amount of code using array_ref and array_set witharrays that *are* known to be ArrayType structures, and there might be moresuch places in third-party code. Rather than cluttering those call siteswith PointerGetDatum/DatumGetArrayTypeP cruft, what I did was to rename theexisting functions to array_get_element/array_set_element, fix theirsignatures, then reincarnate array_ref/array_set as backwards compatibilitywrappers.array_get_slice/array_set_slice have no such constituency in the core code,and probably not in third-party code either, so I just changed their APIs.
1 parentcef3097 commite983c4d

File tree

5 files changed

+180
-142
lines changed

5 files changed

+180
-142
lines changed

‎src/backend/executor/execQual.c

Lines changed: 51 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,6 @@ static Datum ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
252252
*
253253
* NOTE: if we get a NULL result from a subscript expression, we return NULL
254254
* when it's an array reference, or raise an error when it's an assignment.
255-
*
256-
* NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
257-
* even though that might seem natural, because this code needs to support
258-
* both varlena arrays and fixed-length array types. DatumGetArrayTypeP()
259-
* only works for the varlena kind. The routines we call in arrayfuncs.c
260-
* have to know the difference (that's what they need refattrlength for).
261255
*----------
262256
*/
263257
staticDatum
@@ -267,8 +261,7 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
267261
ExprDoneCond*isDone)
268262
{
269263
ArrayRef*arrayRef= (ArrayRef*)astate->xprstate.expr;
270-
ArrayType*array_source;
271-
ArrayType*resultArray;
264+
Datumarray_source;
272265
boolisAssignment= (arrayRef->refassgnexpr!=NULL);
273266
booleisnull;
274267
ListCell*l;
@@ -278,11 +271,10 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
278271
lower;
279272
int*lIndex;
280273

281-
array_source= (ArrayType*)
282-
DatumGetPointer(ExecEvalExpr(astate->refexpr,
283-
econtext,
284-
isNull,
285-
isDone));
274+
array_source=ExecEvalExpr(astate->refexpr,
275+
econtext,
276+
isNull,
277+
isDone);
286278

287279
/*
288280
* If refexpr yields NULL, and it's a fetch, then result is NULL. In the
@@ -390,23 +382,24 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
390382
}
391383
elseif (lIndex==NULL)
392384
{
393-
econtext->caseValue_datum=array_ref(array_source,i,
394-
upper.indx,
395-
astate->refattrlength,
396-
astate->refelemlength,
397-
astate->refelembyval,
398-
astate->refelemalign,
399-
&econtext->caseValue_isNull);
385+
econtext->caseValue_datum=
386+
array_get_element(array_source,i,
387+
upper.indx,
388+
astate->refattrlength,
389+
astate->refelemlength,
390+
astate->refelembyval,
391+
astate->refelemalign,
392+
&econtext->caseValue_isNull);
400393
}
401394
else
402395
{
403-
resultArray=array_get_slice(array_source,i,
404-
upper.indx,lower.indx,
405-
astate->refattrlength,
406-
astate->refelemlength,
407-
astate->refelembyval,
408-
astate->refelemalign);
409-
econtext->caseValue_datum=PointerGetDatum(resultArray);
396+
econtext->caseValue_datum=
397+
array_get_slice(array_source,i,
398+
upper.indx,lower.indx,
399+
astate->refattrlength,
400+
astate->refelemlength,
401+
astate->refelembyval,
402+
astate->refelemalign);
410403
econtext->caseValue_isNull= false;
411404
}
412405
}
@@ -435,7 +428,7 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
435428
*/
436429
if (astate->refattrlength>0)/* fixed-length array? */
437430
if (eisnull||*isNull)
438-
returnPointerGetDatum(array_source);
431+
returnarray_source;
439432

440433
/*
441434
* For assignment to varlena arrays, we handle a NULL original array
@@ -445,48 +438,45 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
445438
*/
446439
if (*isNull)
447440
{
448-
array_source=construct_empty_array(arrayRef->refelemtype);
441+
array_source=PointerGetDatum(construct_empty_array(arrayRef->refelemtype));
449442
*isNull= false;
450443
}
451444

452445
if (lIndex==NULL)
453-
resultArray=array_set(array_source,i,
454-
upper.indx,
455-
sourceData,
456-
eisnull,
457-
astate->refattrlength,
458-
astate->refelemlength,
459-
astate->refelembyval,
460-
astate->refelemalign);
446+
returnarray_set_element(array_source,i,
447+
upper.indx,
448+
sourceData,
449+
eisnull,
450+
astate->refattrlength,
451+
astate->refelemlength,
452+
astate->refelembyval,
453+
astate->refelemalign);
461454
else
462-
resultArray=array_set_slice(array_source,i,
463-
upper.indx,lower.indx,
464-
(ArrayType*)DatumGetPointer(sourceData),
465-
eisnull,
466-
astate->refattrlength,
467-
astate->refelemlength,
468-
astate->refelembyval,
469-
astate->refelemalign);
470-
returnPointerGetDatum(resultArray);
455+
returnarray_set_slice(array_source,i,
456+
upper.indx,lower.indx,
457+
sourceData,
458+
eisnull,
459+
astate->refattrlength,
460+
astate->refelemlength,
461+
astate->refelembyval,
462+
astate->refelemalign);
471463
}
472464

473465
if (lIndex==NULL)
474-
returnarray_ref(array_source,i,upper.indx,
475-
astate->refattrlength,
476-
astate->refelemlength,
477-
astate->refelembyval,
478-
astate->refelemalign,
479-
isNull);
466+
returnarray_get_element(array_source,i,
467+
upper.indx,
468+
astate->refattrlength,
469+
astate->refelemlength,
470+
astate->refelembyval,
471+
astate->refelemalign,
472+
isNull);
480473
else
481-
{
482-
resultArray=array_get_slice(array_source,i,
483-
upper.indx,lower.indx,
484-
astate->refattrlength,
485-
astate->refelemlength,
486-
astate->refelembyval,
487-
astate->refelemalign);
488-
returnPointerGetDatum(resultArray);
489-
}
474+
returnarray_get_slice(array_source,i,
475+
upper.indx,lower.indx,
476+
astate->refattrlength,
477+
astate->refelemlength,
478+
astate->refelembyval,
479+
astate->refelemalign);
490480
}
491481

492482
/*

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
664664
*UPDATE table SET foo[2] = 42, foo[4] = 43;
665665
* We can merge such operations into a single assignment op. Essentially,
666666
* the expression we want to produce in this case is like
667-
*foo =array_set(array_set(foo, 2, 42), 4, 43)
667+
*foo =array_set_element(array_set_element(foo, 2, 42), 4, 43)
668668
*
669669
* 4. Sort the tlist into standard order: non-junk fields in order by resno,
670670
* then junk fields (these in no particular order).

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp