6
6
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
7
7
* Portions Copyright (c) 1994, Regents of the University of California
8
8
*
9
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.290 2003/10/02 06:32:45 petere Exp $
9
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.291 2003/11/05 22:00:46 tgl Exp $
10
10
*
11
11
*-------------------------------------------------------------------------
12
12
*/
@@ -2821,6 +2821,12 @@ CheckSelectForUpdate(Query *qry)
2821
2821
errmsg ("SELECT FOR UPDATE is not allowed with aggregate functions" )));
2822
2822
}
2823
2823
2824
+ /*
2825
+ * Convert FOR UPDATE name list into rowMarks list of integer relids
2826
+ *
2827
+ * NB: if you need to change this, see also markQueryForUpdate()
2828
+ * in rewriteHandler.c.
2829
+ */
2824
2830
static void
2825
2831
transformForUpdate (Query * qry , List * forUpdate )
2826
2832
{
@@ -2833,23 +2839,30 @@ transformForUpdate(Query *qry, List *forUpdate)
2833
2839
2834
2840
if (lfirst (forUpdate ) == NULL )
2835
2841
{
2836
- /* all tables used in query */
2842
+ /* all regular tables used in query */
2837
2843
i = 0 ;
2838
2844
foreach (rt , qry -> rtable )
2839
2845
{
2840
2846
RangeTblEntry * rte = (RangeTblEntry * ) lfirst (rt );
2841
2847
2842
2848
++ i ;
2843
- if (rte -> rtekind == RTE_SUBQUERY )
2844
- {
2845
- /* FOR UPDATE of subquery is propagated to subquery's rels */
2846
- transformForUpdate (rte -> subquery , makeList1 (NULL ));
2847
- }
2848
- else
2849
+ switch (rte -> rtekind )
2849
2850
{
2850
- if (!intMember (i , rowMarks )) /* avoid duplicates */
2851
- rowMarks = lappendi (rowMarks , i );
2852
- rte -> checkForWrite = true;
2851
+ case RTE_RELATION :
2852
+ if (!intMember (i , rowMarks )) /* avoid duplicates */
2853
+ rowMarks = lappendi (rowMarks , i );
2854
+ rte -> checkForWrite = true;
2855
+ break ;
2856
+ case RTE_SUBQUERY :
2857
+ /*
2858
+ * FOR UPDATE of subquery is propagated to subquery's
2859
+ * rels
2860
+ */
2861
+ transformForUpdate (rte -> subquery , makeList1 (NULL ));
2862
+ break ;
2863
+ default :
2864
+ /* ignore JOIN, SPECIAL, FUNCTION RTEs */
2865
+ break ;
2853
2866
}
2854
2867
}
2855
2868
}
@@ -2868,18 +2881,41 @@ transformForUpdate(Query *qry, List *forUpdate)
2868
2881
++ i ;
2869
2882
if (strcmp (rte -> eref -> aliasname , relname ) == 0 )
2870
2883
{
2871
- if (rte -> rtekind == RTE_SUBQUERY )
2884
+ switch (rte -> rtekind )
2872
2885
{
2873
- /* propagate to subquery */
2874
- transformForUpdate (rte -> subquery , makeList1 (NULL ));
2875
- }
2876
- else
2877
- {
2878
- if (!intMember (i , rowMarks )) /* avoid duplicates */
2879
- rowMarks = lappendi (rowMarks , i );
2880
- rte -> checkForWrite = true;
2886
+ case RTE_RELATION :
2887
+ if (!intMember (i , rowMarks )) /* avoid duplicates */
2888
+ rowMarks = lappendi (rowMarks , i );
2889
+ rte -> checkForWrite = true;
2890
+ break ;
2891
+ case RTE_SUBQUERY :
2892
+ /*
2893
+ * FOR UPDATE of subquery is propagated to
2894
+ * subquery's rels
2895
+ */
2896
+ transformForUpdate (rte -> subquery , makeList1 (NULL ));
2897
+ break ;
2898
+ case RTE_JOIN :
2899
+ ereport (ERROR ,
2900
+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
2901
+ errmsg ("SELECT FOR UPDATE cannot be applied to a join" )));
2902
+ break ;
2903
+ case RTE_SPECIAL :
2904
+ ereport (ERROR ,
2905
+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
2906
+ errmsg ("SELECT FOR UPDATE cannot be applied to NEW or OLD" )));
2907
+ break ;
2908
+ case RTE_FUNCTION :
2909
+ ereport (ERROR ,
2910
+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
2911
+ errmsg ("SELECT FOR UPDATE cannot be applied to a function" )));
2912
+ break ;
2913
+ default :
2914
+ elog (ERROR , "unrecognized RTE type: %d" ,
2915
+ (int ) rte -> rtekind );
2916
+ break ;
2881
2917
}
2882
- break ;
2918
+ break ; /* out of foreach loop */
2883
2919
}
2884
2920
}
2885
2921
if (rt == NIL )
0 commit comments