@@ -66,6 +66,7 @@ ExecSubPlan(SubPlanState *node,
6666 SubPlan * subplan = node -> subplan ;
6767 EState * estate = node -> planstate -> state ;
6868 ScanDirection dir = estate -> es_direction ;
69+ int64 save_rownum = estate -> es_rownum ;
6970 Datum retval ;
7071
7172 CHECK_FOR_INTERRUPTS ();
@@ -82,14 +83,22 @@ ExecSubPlan(SubPlanState *node,
8283 /* Force forward-scan mode for evaluation */
8384 estate -> es_direction = ForwardScanDirection ;
8485
86+ /*
87+ * Reset ROWNUM counter for Oracle compatibility.
88+ * Each correlated subquery invocation should start with ROWNUM=0,
89+ * matching Oracle's behavior.
90+ */
91+ estate -> es_rownum = 0 ;
92+
8593 /* Select appropriate evaluation strategy */
8694 if (subplan -> useHashTable )
8795 retval = ExecHashSubPlan (node , econtext , isNull );
8896 else
8997 retval = ExecScanSubPlan (node , econtext , isNull );
9098
91- /* restore scan direction */
99+ /* restore scan direction and ROWNUM counter */
92100 estate -> es_direction = dir ;
101+ estate -> es_rownum = save_rownum ;
93102
94103 return retval ;
95104}
@@ -262,6 +271,12 @@ ExecScanSubPlan(SubPlanState *node,
262271 /* with that done, we can reset the subplan */
263272 ExecReScan (planstate );
264273
274+ /*
275+ * Reset ROWNUM counter for Oracle compatibility.
276+ * This ensures correlated subqueries start fresh for each outer row.
277+ */
278+ planstate -> state -> es_rownum = 0 ;
279+
265280 /*
266281 * For all sublink types except EXPR_SUBLINK and ARRAY_SUBLINK, the result
267282 * is boolean as are the results of the combining operators. We combine
@@ -1104,6 +1119,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
11041119 SubLinkType subLinkType = subplan -> subLinkType ;
11051120 EState * estate = planstate -> state ;
11061121 ScanDirection dir = estate -> es_direction ;
1122+ int64 save_rownum = estate -> es_rownum ;
11071123 MemoryContext oldcontext ;
11081124 TupleTableSlot * slot ;
11091125 ListCell * l ;
@@ -1124,6 +1140,12 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
11241140 */
11251141 estate -> es_direction = ForwardScanDirection ;
11261142
1143+ /*
1144+ * Reset ROWNUM counter for Oracle compatibility.
1145+ * InitPlans should start with ROWNUM=0, matching Oracle's behavior.
1146+ */
1147+ estate -> es_rownum = 0 ;
1148+
11271149 /* Initialize ArrayBuildStateAny in caller's context, if needed */
11281150 if (subLinkType == ARRAY_SUBLINK )
11291151 astate = initArrayResultAny (subplan -> firstColType ,
@@ -1257,8 +1279,9 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
12571279
12581280 MemoryContextSwitchTo (oldcontext );
12591281
1260- /* restore scan direction */
1282+ /* restore scan direction and ROWNUM counter */
12611283 estate -> es_direction = dir ;
1284+ estate -> es_rownum = save_rownum ;
12621285}
12631286
12641287/*
0 commit comments