6
6
* Portions Copyright (c) 1996-2001, 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.188 2001/06/04 16:17:30 tgl Exp $
9
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.189 2001/06/04 23:27:23 momjian Exp $
10
10
*
11
11
*-------------------------------------------------------------------------
12
12
*/
29
29
#include "parser/parse_relation.h"
30
30
#include "parser/parse_target.h"
31
31
#include "parser/parse_type.h"
32
+ #include "parser/parse_expr.h"
32
33
#include "rewrite/rewriteManip.h"
33
34
#include "utils/builtins.h"
34
35
#include "utils/fmgroids.h"
@@ -51,7 +52,10 @@ static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt);
51
52
static Query * transformUpdateStmt (ParseState * pstate , UpdateStmt * stmt );
52
53
static Query * transformCreateStmt (ParseState * pstate , CreateStmt * stmt );
53
54
static Query * transformAlterTableStmt (ParseState * pstate , AlterTableStmt * stmt );
55
+ static Node * transformTypeRefs (ParseState * pstate , Node * stmt );
54
56
57
+ static void transformTypeRefsList (ParseState * pstate , List * l );
58
+ static void transformTypeRef (ParseState * pstate , TypeName * tn );
55
59
static List * getSetColTypes (ParseState * pstate , Node * node );
56
60
static void transformForUpdate (Query * qry , List * forUpdate );
57
61
static void transformFkeyGetPrimaryKey (FkConstraint * fkconstraint , Oid * pktypoid );
@@ -232,6 +236,17 @@ transformStmt(ParseState *pstate, Node *parseTree)
232
236
(SelectStmt * ) parseTree );
233
237
break ;
234
238
239
+ /*
240
+ * Convert use of %TYPE in statements where it is permitted.
241
+ */
242
+ case T_ProcedureStmt :
243
+ case T_CommentStmt :
244
+ case T_RemoveFuncStmt :
245
+ case T_DefineStmt :
246
+ result = makeNode (Query );
247
+ result -> commandType = CMD_UTILITY ;
248
+ result -> utilityStmt = transformTypeRefs (pstate , parseTree );
249
+ break ;
235
250
236
251
default :
237
252
@@ -2701,6 +2716,107 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt)
2701
2716
return qry ;
2702
2717
}
2703
2718
2719
+ /*
2720
+ * Transform uses of %TYPE in a statement.
2721
+ */
2722
+ static Node *
2723
+ transformTypeRefs (ParseState * pstate , Node * stmt )
2724
+ {
2725
+ switch (nodeTag (stmt ))
2726
+ {
2727
+ case T_ProcedureStmt :
2728
+ {
2729
+ ProcedureStmt * ps = (ProcedureStmt * ) stmt ;
2730
+
2731
+ transformTypeRefsList (pstate , ps -> argTypes );
2732
+ transformTypeRef (pstate , (TypeName * ) ps -> returnType );
2733
+ transformTypeRefsList (pstate , ps -> withClause );
2734
+ }
2735
+ break ;
2736
+
2737
+ case T_CommentStmt :
2738
+ {
2739
+ CommentStmt * cs = (CommentStmt * ) stmt ;
2740
+
2741
+ transformTypeRefsList (pstate , cs -> objlist );
2742
+ }
2743
+ break ;
2744
+
2745
+ case T_RemoveFuncStmt :
2746
+ {
2747
+ RemoveFuncStmt * rs = (RemoveFuncStmt * ) stmt ;
2748
+
2749
+ transformTypeRefsList (pstate , rs -> args );
2750
+ }
2751
+ break ;
2752
+
2753
+ case T_DefineStmt :
2754
+ {
2755
+ DefineStmt * ds = (DefineStmt * ) stmt ;
2756
+ List * ele ;
2757
+
2758
+ foreach (ele , ds -> definition )
2759
+ {
2760
+ DefElem * de = (DefElem * ) lfirst (ele );
2761
+
2762
+ if (de -> arg != NULL
2763
+ && IsA (de -> arg , TypeName ))
2764
+ {
2765
+ transformTypeRef (pstate , (TypeName * ) de -> arg );
2766
+ }
2767
+ }
2768
+ }
2769
+ break ;
2770
+
2771
+ default :
2772
+ elog (ERROR , "Unsupported type %d in transformTypeRefs" ,
2773
+ nodeTag (stmt ));
2774
+ break ;
2775
+ }
2776
+
2777
+ return stmt ;
2778
+ }
2779
+
2780
+ /*
2781
+ * Transform uses of %TYPE in a list.
2782
+ */
2783
+ static void
2784
+ transformTypeRefsList (ParseState * pstate , List * l )
2785
+ {
2786
+ List * ele ;
2787
+
2788
+ foreach (ele , l )
2789
+ {
2790
+ if (IsA (lfirst (ele ), TypeName ))
2791
+ transformTypeRef (pstate , (TypeName * ) lfirst (ele ));
2792
+ }
2793
+ }
2794
+
2795
+ /*
2796
+ * Transform a TypeName to not use %TYPE.
2797
+ */
2798
+ static void
2799
+ transformTypeRef (ParseState * pstate , TypeName * tn )
2800
+ {
2801
+ Attr * att ;
2802
+ Node * n ;
2803
+ Var * v ;
2804
+ char * tyn ;
2805
+
2806
+ if (tn -> attrname == NULL )
2807
+ return ;
2808
+ att = makeAttr (tn -> name , tn -> attrname );
2809
+ n = transformExpr (pstate , (Node * ) att , EXPR_COLUMN_FIRST );
2810
+ if (! IsA (n , Var ))
2811
+ elog (ERROR , "unsupported expression in %%TYPE" );
2812
+ v = (Var * ) n ;
2813
+ tyn = typeidTypeName (v -> vartype );
2814
+ elog (NOTICE , "%s.%s%%TYPE converted to %s" , tn -> name , tn -> attrname , tyn );
2815
+ tn -> name = tyn ;
2816
+ tn -> typmod = v -> vartypmod ;
2817
+ tn -> attrname = NULL ;
2818
+ }
2819
+
2704
2820
/* exported so planner can check again after rewriting, query pullup, etc */
2705
2821
void
2706
2822
CheckSelectForUpdate (Query * qry )
0 commit comments