@@ -909,61 +909,68 @@ InitPlan(QueryDesc *queryDesc, int eflags)
909
909
}
910
910
911
911
/*
912
- * Next, build the ExecRowMark list from the PlanRowMark(s), if any.
912
+ * Next, build the ExecRowMark array from the PlanRowMark(s), if any.
913
913
*/
914
- estate -> es_rowMarks = NIL ;
915
- foreach (l , plannedstmt -> rowMarks )
914
+ if (plannedstmt -> rowMarks )
916
915
{
917
- PlanRowMark * rc = (PlanRowMark * ) lfirst (l );
918
- Oid relid ;
919
- Relation relation ;
920
- ExecRowMark * erm ;
916
+ estate -> es_rowmarks = (ExecRowMark * * )
917
+ palloc0 (estate -> es_range_table_size * sizeof (ExecRowMark * ));
918
+ foreach (l , plannedstmt -> rowMarks )
919
+ {
920
+ PlanRowMark * rc = (PlanRowMark * ) lfirst (l );
921
+ Oid relid ;
922
+ Relation relation ;
923
+ ExecRowMark * erm ;
921
924
922
- /* ignore "parent" rowmarks; they are irrelevant at runtime */
923
- if (rc -> isParent )
924
- continue ;
925
+ /* ignore "parent" rowmarks; they are irrelevant at runtime */
926
+ if (rc -> isParent )
927
+ continue ;
925
928
926
- /* get relation's OID (will produce InvalidOid if subquery) */
927
- relid = exec_rt_fetch (rc -> rti , estate )-> relid ;
929
+ /* get relation's OID (will produce InvalidOid if subquery) */
930
+ relid = exec_rt_fetch (rc -> rti , estate )-> relid ;
928
931
929
- /* open relation, if we need to access it for this mark type */
930
- switch (rc -> markType )
931
- {
932
- case ROW_MARK_EXCLUSIVE :
933
- case ROW_MARK_NOKEYEXCLUSIVE :
934
- case ROW_MARK_SHARE :
935
- case ROW_MARK_KEYSHARE :
936
- case ROW_MARK_REFERENCE :
937
- relation = ExecGetRangeTableRelation (estate , rc -> rti );
938
- break ;
939
- case ROW_MARK_COPY :
940
- /* no physical table access is required */
941
- relation = NULL ;
942
- break ;
943
- default :
944
- elog (ERROR , "unrecognized markType: %d" , rc -> markType );
945
- relation = NULL ; /* keep compiler quiet */
946
- break ;
947
- }
932
+ /* open relation, if we need to access it for this mark type */
933
+ switch (rc -> markType )
934
+ {
935
+ case ROW_MARK_EXCLUSIVE :
936
+ case ROW_MARK_NOKEYEXCLUSIVE :
937
+ case ROW_MARK_SHARE :
938
+ case ROW_MARK_KEYSHARE :
939
+ case ROW_MARK_REFERENCE :
940
+ relation = ExecGetRangeTableRelation (estate , rc -> rti );
941
+ break ;
942
+ case ROW_MARK_COPY :
943
+ /* no physical table access is required */
944
+ relation = NULL ;
945
+ break ;
946
+ default :
947
+ elog (ERROR , "unrecognized markType: %d" , rc -> markType );
948
+ relation = NULL ; /* keep compiler quiet */
949
+ break ;
950
+ }
948
951
949
- /* Check that relation is a legal target for marking */
950
- if (relation )
951
- CheckValidRowMarkRel (relation , rc -> markType );
952
-
953
- erm = (ExecRowMark * ) palloc (sizeof (ExecRowMark ));
954
- erm -> relation = relation ;
955
- erm -> relid = relid ;
956
- erm -> rti = rc -> rti ;
957
- erm -> prti = rc -> prti ;
958
- erm -> rowmarkId = rc -> rowmarkId ;
959
- erm -> markType = rc -> markType ;
960
- erm -> strength = rc -> strength ;
961
- erm -> waitPolicy = rc -> waitPolicy ;
962
- erm -> ermActive = false;
963
- ItemPointerSetInvalid (& (erm -> curCtid ));
964
- erm -> ermExtra = NULL ;
965
-
966
- estate -> es_rowMarks = lappend (estate -> es_rowMarks , erm );
952
+ /* Check that relation is a legal target for marking */
953
+ if (relation )
954
+ CheckValidRowMarkRel (relation , rc -> markType );
955
+
956
+ erm = (ExecRowMark * ) palloc (sizeof (ExecRowMark ));
957
+ erm -> relation = relation ;
958
+ erm -> relid = relid ;
959
+ erm -> rti = rc -> rti ;
960
+ erm -> prti = rc -> prti ;
961
+ erm -> rowmarkId = rc -> rowmarkId ;
962
+ erm -> markType = rc -> markType ;
963
+ erm -> strength = rc -> strength ;
964
+ erm -> waitPolicy = rc -> waitPolicy ;
965
+ erm -> ermActive = false;
966
+ ItemPointerSetInvalid (& (erm -> curCtid ));
967
+ erm -> ermExtra = NULL ;
968
+
969
+ Assert (erm -> rti > 0 && erm -> rti <= estate -> es_range_table_size &&
970
+ estate -> es_rowmarks [erm -> rti - 1 ] == NULL );
971
+
972
+ estate -> es_rowmarks [erm -> rti - 1 ] = erm ;
973
+ }
967
974
}
968
975
969
976
/*
@@ -2394,13 +2401,12 @@ ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo)
2394
2401
ExecRowMark *
2395
2402
ExecFindRowMark (EState * estate , Index rti , bool missing_ok )
2396
2403
{
2397
- ListCell * lc ;
2398
-
2399
- foreach (lc , estate -> es_rowMarks )
2404
+ if (rti > 0 && rti <= estate -> es_range_table_size &&
2405
+ estate -> es_rowmarks != NULL )
2400
2406
{
2401
- ExecRowMark * erm = ( ExecRowMark * ) lfirst ( lc ) ;
2407
+ ExecRowMark * erm = estate -> es_rowmarks [ rti - 1 ] ;
2402
2408
2403
- if (erm -> rti == rti )
2409
+ if (erm )
2404
2410
return erm ;
2405
2411
}
2406
2412
if (!missing_ok )
@@ -3131,6 +3137,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
3131
3137
estate -> es_range_table_array = parentestate -> es_range_table_array ;
3132
3138
estate -> es_range_table_size = parentestate -> es_range_table_size ;
3133
3139
estate -> es_relations = parentestate -> es_relations ;
3140
+ estate -> es_rowmarks = parentestate -> es_rowmarks ;
3134
3141
estate -> es_plannedstmt = parentestate -> es_plannedstmt ;
3135
3142
estate -> es_junkFilter = parentestate -> es_junkFilter ;
3136
3143
estate -> es_output_cid = parentestate -> es_output_cid ;
@@ -3148,7 +3155,6 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
3148
3155
}
3149
3156
/* es_result_relation_info must NOT be copied */
3150
3157
/* es_trig_target_relations must NOT be copied */
3151
- estate -> es_rowMarks = parentestate -> es_rowMarks ;
3152
3158
estate -> es_top_eflags = parentestate -> es_top_eflags ;
3153
3159
estate -> es_instrument = parentestate -> es_instrument ;
3154
3160
/* es_auxmodifytables must NOT be copied */
0 commit comments