|
6 | 6 | *
|
7 | 7 | *
|
8 | 8 | * IDENTIFICATION
|
9 |
| - * $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.22 1999/09/18 19:07:18 tgl Exp $ |
| 9 | + * $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.23 1999/10/01 04:08:24 tgl Exp $ |
10 | 10 | *
|
11 | 11 | *-------------------------------------------------------------------------
|
12 | 12 | */
|
13 | 13 | #include"postgres.h"
|
14 | 14 |
|
15 | 15 | #include"access/heapam.h"
|
16 | 16 | #include"catalog/pg_shadow.h"
|
| 17 | +#include"optimizer/clauses.h" |
17 | 18 | #include"rewrite/locks.h"
|
18 | 19 | #include"utils/acl.h"
|
19 | 20 | #include"utils/builtins.h"
|
|
22 | 23 |
|
23 | 24 |
|
24 | 25 | /*
|
25 |
| - *ThisLockWasTriggered |
| 26 | + *thisLockWasTriggered |
26 | 27 | *
|
27 | 28 | * walk the tree, if there we find a varnode,
|
28 | 29 | * we check the varattno against the attnum
|
29 | 30 | * if we find at least one such match, we return true
|
30 | 31 | * otherwise, we return false
|
| 32 | + * |
| 33 | + * XXX this should be unified with attribute_used() |
31 | 34 | */
|
| 35 | + |
| 36 | +typedefstruct { |
| 37 | +intvarno; |
| 38 | +intattnum; |
| 39 | +intsublevels_up; |
| 40 | +}thisLockWasTriggered_context; |
| 41 | + |
32 | 42 | staticbool
|
33 |
| -nodeThisLockWasTriggered(Node*node,intvarno,AttrNumberattnum, |
34 |
| -intsublevels_up) |
| 43 | +thisLockWasTriggered_walker(Node*node, |
| 44 | +thisLockWasTriggered_context*context) |
35 | 45 | {
|
36 | 46 | if (node==NULL)
|
37 |
| -returnFALSE; |
38 |
| -switch (nodeTag(node)) |
| 47 | +returnfalse; |
| 48 | +if (IsA(node,Var)) |
39 | 49 | {
|
40 |
| -caseT_Var: |
41 |
| -{ |
42 |
| -Var*var= (Var*)node; |
| 50 | +Var*var= (Var*)node; |
43 | 51 |
|
44 |
| -if (varno==var->varno&& |
45 |
| -(attnum==var->varattno||attnum==-1)) |
46 |
| -return TRUE; |
47 |
| -} |
48 |
| -break; |
49 |
| -caseT_Expr: |
50 |
| -{ |
51 |
| -Expr*expr= (Expr*)node; |
52 |
| - |
53 |
| -returnnodeThisLockWasTriggered((Node*)expr->args,varno, |
54 |
| -attnum,sublevels_up); |
55 |
| -} |
56 |
| -break; |
57 |
| -caseT_TargetEntry: |
58 |
| -{ |
59 |
| -TargetEntry*tle= (TargetEntry*)node; |
60 |
| - |
61 |
| -returnnodeThisLockWasTriggered(tle->expr,varno,attnum, |
62 |
| -sublevels_up); |
63 |
| -} |
64 |
| -break; |
65 |
| -caseT_Aggref: |
66 |
| -{ |
67 |
| -Aggref*aggref= (Aggref*)node; |
68 |
| - |
69 |
| -returnnodeThisLockWasTriggered(aggref->target,varno,attnum, |
70 |
| -sublevels_up); |
71 |
| -} |
72 |
| -break; |
73 |
| -caseT_List: |
74 |
| -{ |
75 |
| -List*l; |
76 |
| - |
77 |
| -foreach(l, (List*)node) |
78 |
| -{ |
79 |
| -if (nodeThisLockWasTriggered(lfirst(l),varno,attnum, |
80 |
| -sublevels_up)) |
81 |
| -return TRUE; |
82 |
| -} |
83 |
| -return FALSE; |
84 |
| -} |
85 |
| -break; |
86 |
| -caseT_SubLink: |
87 |
| -{ |
88 |
| -SubLink*sublink= (SubLink*)node; |
89 |
| -Query*query= (Query*)sublink->subselect; |
| 52 | +if (var->varlevelsup==context->sublevels_up&& |
| 53 | +var->varno==context->varno&& |
| 54 | +(var->varattno==context->attnum||context->attnum==-1)) |
| 55 | +return true; |
| 56 | +return false; |
| 57 | +} |
| 58 | +if (IsA(node,SubLink)) |
| 59 | +{ |
| 60 | +/* |
| 61 | + * Standard expression_tree_walker will not recurse into subselect, |
| 62 | + * but here we must do so. |
| 63 | + */ |
| 64 | +SubLink*sub= (SubLink*)node; |
90 | 65 |
|
91 |
| -returnnodeThisLockWasTriggered(query->qual,varno,attnum, |
92 |
| -sublevels_up+1); |
93 |
| -} |
94 |
| -break; |
95 |
| -default: |
96 |
| -break; |
| 66 | +if (thisLockWasTriggered_walker((Node*) (sub->lefthand),context)) |
| 67 | +return true; |
| 68 | +context->sublevels_up++; |
| 69 | +if (thisLockWasTriggered_walker((Node*) (sub->subselect),context)) |
| 70 | +{ |
| 71 | +context->sublevels_up--;/* not really necessary */ |
| 72 | +return true; |
| 73 | +} |
| 74 | +context->sublevels_up--; |
| 75 | +return false; |
| 76 | +} |
| 77 | +if (IsA(node,Query)) |
| 78 | +{ |
| 79 | +/* Reach here after recursing down into subselect above... */ |
| 80 | +Query*qry= (Query*)node; |
| 81 | + |
| 82 | +if (thisLockWasTriggered_walker((Node*) (qry->targetList),context)) |
| 83 | +return true; |
| 84 | +if (thisLockWasTriggered_walker((Node*) (qry->qual),context)) |
| 85 | +return true; |
| 86 | +if (thisLockWasTriggered_walker((Node*) (qry->havingQual),context)) |
| 87 | +return true; |
| 88 | +return false; |
97 | 89 | }
|
98 |
| -return FALSE; |
| 90 | +returnexpression_tree_walker(node,thisLockWasTriggered_walker, |
| 91 | + (void*)context); |
99 | 92 | }
|
100 | 93 |
|
101 |
| -/* |
102 |
| - * thisLockWasTriggered - |
103 |
| - * walk the tree, if there we find a varnode, we check the varattno |
104 |
| - * against the attnum if we find at least one such match, we return true |
105 |
| - * otherwise, we return false |
106 |
| - */ |
107 | 94 | staticbool
|
108 | 95 | thisLockWasTriggered(intvarno,
|
109 |
| -AttrNumberattnum, |
| 96 | +intattnum, |
110 | 97 | Query*parsetree)
|
111 | 98 | {
|
| 99 | +thisLockWasTriggered_contextcontext; |
112 | 100 |
|
113 |
| -if (nodeThisLockWasTriggered(parsetree->qual,varno,attnum,0)) |
114 |
| -return true; |
115 |
| - |
116 |
| -if (nodeThisLockWasTriggered((Node*)parsetree->targetList,varno,attnum,0)) |
117 |
| -return true; |
118 |
| - |
119 |
| -return false; |
| 101 | +context.varno=varno; |
| 102 | +context.attnum=attnum; |
| 103 | +context.sublevels_up=0; |
120 | 104 |
|
| 105 | +returnthisLockWasTriggered_walker((Node*)parsetree,&context); |
121 | 106 | }
|
122 | 107 |
|
123 | 108 | /*
|
|