]> git.8kb.co.uk Git - pgpool-ii/pgpool-ii_2.2.5/blob - pool_rewrite_outfuncs.c
Attempt to send a proper failure message to frontend when authentication
[pgpool-ii/pgpool-ii_2.2.5] / pool_rewrite_outfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * outfuncs.c
4  *        Output functions for Postgres tree nodes.
5  *
6  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/dblink/nodes/outfuncs.c,v 1.261.2.1 2005/11/14 23:54:34 tgl Exp $
12  *
13  * NOTES
14  *        Every node type that can appear in stored rules' parsetrees *must*
15  *        have an output function defined here (as well as an input function
16  *        in readfuncs.c).      For use in debugging, we also provide output
17  *        functions for nodes that appear in raw parsetrees, path, and plan trees.
18  *        These nodes however need not have input functions.
19  *
20  *-------------------------------------------------------------------------
21  */
22 #include <string.h>
23 #include <limits.h>
24
25 #include "pool.h"
26 #include "parser/parser.h"
27 #include "parser/pool_string.h"
28 #include "parser/pg_list.h"
29 #include "parser/parsenodes.h"
30 #include "pool_rewrite_query.h"
31
32 #define booltostr(x)  ((x) ? "true" : "false")
33
34
35 extern void _outNode(String *str, void *obj);
36 static void _rewriteNode(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, void *obj);
37 static void _rewriteList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *node);
38 static void _rewriteIdList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *node);
39 static void _rewriteAlias(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Alias *node);
40 static void _rewriteRangeVar(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RangeVar *node);
41 static void _rewriteVar(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Var *node);
42 static void _rewriteConst(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Const *node);
43 static void _rewriteParam(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Param *node);
44 static void _rewriteAggref(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Aggref *node);
45 static void _rewriteArrayRef(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ArrayRef *node);
46 static void _rewriteFuncExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FuncExpr *node);
47 static void _rewriteOpExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, OpExpr *node);
48 static void _rewriteDistinctExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DistinctExpr *node);
49 static void _rewriteScalarArrayOpExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ScalarArrayOpExpr *node);
50 static void _rewriteBoolExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, BoolExpr *node);
51 static void _rewriteSubLink(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SubLink *node);
52 static void _rewriteSubPlan(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SubPlan *node);
53 static void _rewriteFieldSelect(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FieldSelect *node);
54 static void _rewriteFieldStore(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FieldStore *node);
55 static void _rewriteRelabelType(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RelabelType *node);
56 static void _rewriteConvertRowtypeExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ConvertRowtypeExpr *node);
57 static void _rewriteCaseExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CaseExpr *node);
58 static void _rewriteCaseWhen(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CaseWhen *node);
59 static void _rewriteCaseTestExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CaseTestExpr *node);
60 static void _rewriteArrayExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ArrayExpr *node);
61 static void _rewriteRowExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RowExpr *node);
62 static void _rewriteCoalesceExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CoalesceExpr *node);
63 static void _rewriteMinMaxExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, MinMaxExpr *node);
64 static void _rewriteNullIfExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, NullIfExpr *node);
65 static void _rewriteNullTest(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, NullTest *node);
66 static void _rewriteBooleanTest(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, BooleanTest *node);
67 static void _rewriteCoerceToDomain(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CoerceToDomain *node);
68 static void _rewriteCoerceToDomainValue(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CoerceToDomainValue *node);
69 static void _rewriteSetToDefault(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SetToDefault *node);
70 static void _rewriteTargetEntry(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, TargetEntry *node);
71 static void _rewriteRangeTblRef(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RangeTblRef *node);
72 static void _rewriteJoinExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, JoinExpr *node);
73 static void _rewriteFromExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FromExpr *node);
74 static void _rewriteCreateStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateStmt *node);
75 static void _rewriteIndexStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, IndexStmt *node);
76 static void _rewriteNotifyStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, NotifyStmt *node);
77 static void _rewriteDeclareCursorStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DeclareCursorStmt *node);
78 static void _rewriteSelectStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SelectStmt *node);
79 static void _rewriteFuncCall(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FuncCall *node);
80 static void _rewriteDefElem(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DefElem *node);
81 static void _rewriteLockingClause(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, LockingClause *node);
82 static void _rewriteColumnDef(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ColumnDef *node);
83 static void _rewriteTypeName(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, TypeName *node);
84 static void _rewriteTypeCast(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, TypeCast *node);
85 static void _rewriteIndexElem(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, IndexElem *node);
86 static void _rewriteSortClause(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SortClause *node);
87 static void _rewriteGroupClause(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, GroupClause *node);
88 static void _rewriteSetOperationStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SetOperationStmt *node);
89 static void _rewriteAExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, A_Expr *node);
90 static void _rewriteValue(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Value *value);
91 static void _rewriteColumnRef(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ColumnRef *node);
92 static void _rewriteParamRef(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ParamRef *node);
93 static void _rewriteAConst(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, A_Const *node);
94 static void _rewriteA_Indices(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, A_Indices *node);
95 static void _rewriteA_Indirection(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, A_Indirection *node);
96 static void _rewriteResTarget(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ResTarget *node);
97 static void _rewriteConstraint(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Constraint *node);
98 static void _rewriteFkConstraint(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FkConstraint *node);
99
100 static void _rewriteSortBy(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SortBy *node);
101 static void _rewriteInsertStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, InsertStmt *node);
102 static void _rewriteUpdateStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, UpdateStmt *node);
103 static void _rewriteDeleteStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DeleteStmt *node);
104 static void _rewriteTransactionStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, TransactionStmt *node);
105 static void _rewriteTruncateStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, TruncateStmt *node);
106 static void _rewriteVacuumStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, VacuumStmt *node);
107 static void _rewriteExplainStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ExplainStmt *node);
108 static void _rewriteClusterStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ClusterStmt *node);
109 static void _rewriteCheckPointStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CheckPointStmt *node);
110 static void _rewriteClosePortalStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ClosePortalStmt *node);
111 static void _rewriteListenStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ListenStmt *node);
112 static void _rewriteUnlistenStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, UnlistenStmt *node);
113 static void _rewriteLoadStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, LoadStmt *node);
114 static void _rewriteCopyStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CopyStmt *node);
115 static void _rewriteDeallocateStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DeallocateStmt *node);
116 static void _rewriteRenameStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RenameStmt *node);
117 static void _rewriteCreateRoleStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateRoleStmt *node);
118 static void _rewriteAlterRoleStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterRoleStmt *node);
119 static void _rewriteDropRoleStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropRoleStmt *node);
120 static void _rewriteCreateSchemaStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateSchemaStmt *node);
121 static void _rewriteVariableSetStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, VariableSetStmt *node);
122 static void _rewriteVariableShowStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, VariableShowStmt *node);
123 static void _rewriteConstraintsSetStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ConstraintsSetStmt *node);
124 static void _rewriteAlterTableStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterTableStmt *node);
125 static void _rewriteCreateSeqStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateSeqStmt *node);
126 static void _rewriteAlterSeqStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterSeqStmt *node);
127 static void _rewriteCreatePLangStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreatePLangStmt *node);
128 static void _rewriteDropPLangStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropPLangStmt *node);
129 static void _rewriteCreateTableSpaceStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateTableSpaceStmt *node);
130 static void _rewriteDropTableSpaceStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropTableSpaceStmt *node);
131 static void _rewriteCreateTrigStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateTrigStmt *node);
132 static void _rewriteDropPropertyStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropPropertyStmt *node);
133 static void _rewriteDefineStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DefineStmt *node);
134 static void _rewriteCreateOpClassStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateOpClassStmt *node);
135 static void _rewriteRemoveOpClassStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RemoveOpClassStmt *node);
136 static void _rewriteDropStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropStmt *node);
137 static void _rewriteFetchStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FetchStmt *node);
138 static void _rewriteGrantStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, GrantStmt *node);
139 static void _rewriteGrantRoleStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, GrantRoleStmt *node);
140 static void _rewriteCreateFunctionStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateFunctionStmt *node);
141 static void _rewriteAlterFunctionStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterFunctionStmt *node);
142 static void _rewriteRemoveFuncStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RemoveFuncStmt *node);
143 static void _rewriteCreateCastStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateCastStmt *node);
144 static void _rewriteDropCastStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropCastStmt *node);
145 static void _rewriteReindexStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ReindexStmt *node);
146 static void _rewriteRuleStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RuleStmt *node);
147 static void _rewriteViewStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ViewStmt *node);
148 static void _rewriteCreatedbStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreatedbStmt *node);
149 static void _rewriteAlterDatabaseStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterDatabaseStmt *node);
150 static void _rewriteAlterDatabaseSetStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterDatabaseSetStmt *node);
151 static void _rewriteDropdbStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropdbStmt *node);
152 static void _rewriteCreateDomainStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateDomainStmt *node);
153 static void _rewriteAlterDomainStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterDomainStmt *node);
154 static void _rewriteCreateConversionStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateConversionStmt *node);
155 static void _rewritePrepareStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, PrepareStmt *node);
156 static void _rewriteExecuteStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ExecuteStmt *node);
157 static void _rewriteLockStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, LockStmt *node);
158 static void _rewriteCommentStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CommentStmt *node);
159
160 static void _rewriteFuncName(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *func_name);
161 static void _rewriteSetRest(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, VariableSetStmt *node);
162 static void _rewriteSetTransactionModeList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *list);
163 static void _rewriteAlterTableCmd(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterTableCmd *node);
164 static void _rewriteOptSeqList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *options);
165 static void _rewritePrivGrantee(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, PrivGrantee *node);
166 static void _rewritePrivTarget(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, PrivTarget *node);
167 static void _rewriteFuncWithArgs(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FuncWithArgs *node);
168 static void _rewriteFunctionParameter(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FunctionParameter *node);
169 static void _rewritePrivilegeList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *list);
170 static void _rewriteFuncOptList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *list);
171 static void _rewriteCreatedbOptList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *options);
172 static void _rewriteOperatorArgTypes(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *args);
173 static void _rewriteRangeFunction(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RangeFunction *node);
174 static void _rewriteWithDefinition(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *def_list);
175
176 /* analyze */
177 static void KeepRewriteQueryCode(RewriteQuery *message, int current_select);
178 static void KeepMessages(RewriteQuery *message,int current_select,int part);
179 static int CheckWhereCaluse(Node *BaseSelect,RewriteQuery *message,ConInfoTodblink *dblink,String *str,int true_count);
180 static int _writewhereClause(A_Expr *expr,RewriteQuery *message,ConInfoTodblink *dblink, String *str,int true_count);
181 static char *escape_string(char *str);
182 static void delay_string_append_char(RewriteQuery *message,String *str, char *parts);
183 static void build_range_info(RewriteQuery *message,DistDefInfo *info,RepliDefInfo *info2,SelectDefInfo *info3,char *alias,int select_num,int i_num);
184 static void AnalyzeReturnRecord(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *list);
185 static void build_virtual_table(RewriteQuery *message,void *obj, int next);
186 static char *search_type_from_virtual(VirtualTable *virtual,char *table,char *col);
187 static int _checkVirtualColumn(ColumnRef *col,RewriteQuery *message);
188 static void SeekColumnName(Aggexpr *agg,ColumnRef *node,int state);
189 /* rewirte */
190 static void writeSelectHeader(RewriteQuery *message,ConInfoTodblink *dblink, String *str,int parallel,int state);
191 static void writeSelectFooter(RewriteQuery *message,String *str,AnalyzeSelect *analyze,int state);
192 static void KeepRewriteQueryReturnCode(RewriteQuery *message, int r_code);
193 static void writeRangeHeader(RewriteQuery *message,ConInfoTodblink *dblink, String *str,DistDefInfo *info, RepliDefInfo *info2,char *alias);
194 static void writeRangeFooter(RewriteQuery *message,ConInfoTodblink *dblink, String *str,DistDefInfo *info, RepliDefInfo *info2,char *alias);
195 static bool CheckAggOpt(RewriteQuery *message);
196 static char *GetNameFromColumnRef(ColumnRef *node,bool state);
197 static void AvgFuncCall(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FuncCall *node);
198
199 /* under define is used in _rewritejoinExpr */
200 #define JDEFAULT 0
201 #define JNORMAL  1
202 #define JNATURAL_INNER  2
203 #define JNATURAL_LEFT  3
204 #define JNATURAL_RIGHT 4
205 #define JNATURAL_FULL  5
206 #define JINNER   6
207 #define JLEFT    7
208 #define JRIGHT   8
209 #define JFULL    9
210 #define JUSING   10
211
212 #define LOADBALANCE false
213 #define PARALLEL true
214
215 #define SELECT_START -1
216 #define SELECT_FROMCLAUSE 0
217 #define SELECT_TARGETLIST 1
218 #define SELECT_WHERECLAUSE 2
219 #define SELECT_GROUPBYCLAUSE 3
220 #define SELECT_HAVINGCLAUSE 4
221 #define SELECT_SORTCLAUSE 5
222 #define SELECT_OFFSETCLAUSE 6
223 #define SELECT_LIMITCLAUSE 7
224 #define SELECT_OTHER 8
225
226 static char *escape_string(char *str)
227 {
228         int len = strlen(str), i, j;
229         char *es = palloc0(len * 2 + 1);
230
231         if (es == NULL)
232         {
233                 return NULL;
234         }
235
236         for (i = 0, j = 0; i < len; i++, j++)
237         {
238                 if (str[i] == '\'')
239                 {
240                         es[j++] = '\'';
241                 }
242                 else if (str[i] == '\\')
243                 {
244                         es[j++] = '\\';
245                 }
246                 es[j] = str[i];
247         }
248
249         return es;
250 }
251
252 static void
253 delay_string_append_char(RewriteQuery *message,String *str, char *parts)
254 {
255         if(message->r_code == SELECT_DEFAULT && message->ignore_rewrite == -1)
256         {
257                 if(parts)
258                 {
259                         string_append_char( str, parts);
260 #ifdef DEBUG
261                         pool_debug("debug Rewrite  Query %s", str->data);
262 #endif
263                 }
264                 else
265                         message->r_code = SELECT_RELATION_ERROR;
266         }
267 }
268
269
270 /*
271  * Is this column  member of table (message->table_relname) ?
272  * return 1 -- member
273  * return 0 or -1 -- not mmeber
274  */
275 static int
276 _checkVirtualColumn(ColumnRef *col,RewriteQuery *message)
277 {
278         ListCell *c;
279         List *list;
280         VirtualTable *virtual = NULL;
281         AnalyzeSelect *analyze = NULL;
282         char first = 0;
283         char *tmp_table = NULL;
284         char *colname = NULL;
285         char *table = NULL;
286         int check_col = 0;
287         int no = message->current_select;
288         int v_colnum;
289         int i;
290
291         list = col->fields;
292         analyze = message->analyze[no];
293
294         if(list->length > 2 || list->length == 0)
295         {
296                 /* send error message */
297                 return -1;
298         }
299
300         foreach (c, col->fields)
301         {
302                 Node *n = (Node *) lfirst(c);
303
304                 if (IsA(n, String))
305                 {
306                         Value *v = (Value *) lfirst(c);
307                         if(list->length == 2 && first == 0)
308                         {
309                                 first = 1;
310                                 tmp_table = v->val.str;
311                         }
312                         else
313                                 colname = v->val.str;
314                 }
315         }
316
317         if(analyze->partstate[SELECT_FROMCLAUSE] == 'S')
318         {
319                 if (message->table_relname)
320                 {
321                         if(tmp_table && strcmp(message->table_relname,tmp_table) != 0)
322                         {
323                                 return check_col;
324                         }
325                         table = message->table_relname;
326                 }
327                 else
328                 {
329                                 return check_col;
330                 }
331
332                 virtual = analyze->virtual;
333                 v_colnum = virtual->col_num;
334
335                 for(i = 0; i < v_colnum; i++)
336                 {
337                         if(!strcmp(virtual->table_list[i],table) &&
338                                         !strcmp(virtual->col_list[i],colname))
339                         {
340                                         check_col = 1;
341                                         break;
342                         }
343                 }
344         } else {
345                 virtual = analyze->virtual;
346                 v_colnum = virtual->col_num;
347
348                 for(i = 0; i < v_colnum; i++)
349                 {
350                         if(tmp_table)
351                         {
352                                 if(!strcmp(virtual->table_list[i],tmp_table) &&
353                                         !strcmp(virtual->col_list[i],colname))
354                                 {
355                                         check_col = 1;
356                                         break;
357                                 }
358                         }
359                         else
360                         {
361                                 if(!strcmp(virtual->col_list[i],colname))
362                                 {
363                                         check_col = 1;
364                                         break;
365                                 }
366                         }
367                 }
368         }
369         return check_col;
370 }
371
372 static void KeepMessages(RewriteQuery *message,int current_select,int part)
373 {
374         message->current_select = current_select;
375         message->part = part;
376 }
377
378 static void KeepRewriteQueryCode(RewriteQuery *message, int current_select)
379 {
380                 message->current_select = current_select;
381 }
382
383 static void KeepRewriteQueryReturnCode(RewriteQuery *message, int r_code)
384 {
385  if((message->r_code != SELECT_RELATION_ERROR)
386       && (message->r_code != SELECT_PGCATALOG))
387     message->r_code = r_code;
388 }
389
390 /*
391  * A_Expr check
392  * if A_Expr-tree use subquery,function,or other table member
393  * rewrite expression as "TRUE"
394  *
395  * return value is counter of rewriting query.
396  */
397 static int
398 _writewhereClause(A_Expr *expr,RewriteQuery *message,ConInfoTodblink *dblink, String *str,int true_count)
399 {
400         int message_r_code = message->r_code;
401
402         switch (expr->kind)
403         {
404                 case AEXPR_OP:
405                         if (list_length(expr->name) == 1)
406                         {
407                                 KeepRewriteQueryReturnCode(message, SELECT_AEXPR);
408                                 _rewriteNode(NULL, message, dblink, str, expr->lexpr);
409                                 if(message->r_code == SELECT_AEXPR)
410                                 {
411                                         _rewriteNode(NULL, message, dblink, str, expr->rexpr);
412                                         if(message->r_code == SELECT_AEXPR)
413                                         {
414                                                 Value *op = (Value *) lfirst(list_head(expr->name));
415                                                 KeepRewriteQueryReturnCode(message, message_r_code);
416                                                 _rewriteNode(NULL, message, dblink, str, expr->lexpr);
417                                                 delay_string_append_char(message, str, op->val.str);
418                                                 _rewriteNode(NULL, message, dblink, str, expr->rexpr);
419                                                 KeepRewriteQueryReturnCode(message, message_r_code);
420                                         } else {
421                                                 KeepRewriteQueryReturnCode(message, message_r_code);
422                                                 delay_string_append_char(message, str,"TRUE");
423                                                 true_count++;
424                                                 break;
425                                         }
426                                 } else {
427                                         KeepRewriteQueryReturnCode(message, message_r_code);
428                                         delay_string_append_char(message, str,"TRUE");
429                                         true_count++;
430                                 }
431                                 break;
432                         }
433                         else
434                         {
435                                 delay_string_append_char(message, str,"TRUE");
436                                 true_count++;
437                         }
438                         break;
439
440                 case AEXPR_AND:
441                         delay_string_append_char(message, str, " (");
442                         true_count = true_count + CheckWhereCaluse(expr->lexpr,message,dblink,str,true_count);
443                         delay_string_append_char(message, str, " AND ");
444                         true_count = true_count + CheckWhereCaluse(expr->rexpr,message,dblink,str,true_count);
445                         delay_string_append_char(message, str, ")");
446                         break;
447
448                 case AEXPR_OR:
449                         delay_string_append_char(message, str, " (");
450                         true_count = true_count + CheckWhereCaluse(expr->lexpr,message,dblink,str,true_count);
451                         delay_string_append_char(message, str, " OR ");
452                         true_count = true_count +  CheckWhereCaluse(expr->rexpr,message,dblink,str,true_count);
453                         delay_string_append_char(message, str, ")");
454                         break;
455
456                 case AEXPR_OP_ANY:
457                         /* not implemented yet */
458                          break;
459
460                 case AEXPR_OP_ALL:
461                         /* not implemented yet */
462                         break;
463 #if 0
464
465                 case AEXPR_NOT:
466                         delay_string_append_char(message, str, " (NOT ");
467                         CheckWhereCaluse(expr->rexpr,str,tablename,dbname, schemaname,aliasname);
468                         delay_string_append_char(message, str, ")");
469                         break;
470
471                 case AEXPR_DISTINCT:
472                         delay_string_append_char(message, str, " (");
473                         _rewriteNode(BaseSelect, message, dblink, str, node->lexpr);
474                         delay_string_append_char(message, str, " IS DISTINCT FROM ");
475                         _rewriteNode(BaseSelect, message, dblink, str, node->rexpr);
476                         delay_string_append_char(message, str, ")");
477                         break;
478
479                 case AEXPR_NULLIF:
480                         delay_string_append_char(message, str, " NULLIF(");
481                         _rewriteNode(BaseSelect, message, dblink, str, node->lexpr);
482                         delay_string_append_char(message, str, ", ");
483                         _rewriteNode(BaseSelect, message, dblink, str, node->rexpr);
484                         delay_string_append_char(message, str, ")");
485                         break;
486
487                 case AEXPR_OF:
488                         _rewriteNode(BaseSelect, message, dblink, str, node->lexpr);
489                         if (*(char *)lfirst(list_head(node->name)) == '!')
490                                 delay_string_append_char(message, str, " IS NOT OF (");
491                         else
492                                 delay_string_append_char(message, str, " IS OF (");
493                                 _rewriteNode(BaseSelect, message, dblink, str, node->rexpr);
494                                 delay_string_append_char(message, str, ")");
495                         break;
496 #endif
497                 default:
498                         delay_string_append_char(message, str,"TRUE");
499                         true_count++;
500                         break;
501         }
502         return true_count;
503 }
504
505 /*
506  *  Start whereClasue check
507  *  call _writewherelause();
508  *
509  *  if messgae->r_code is SELECT DEFAULT,
510  *      write down whereClause
511  *  else
512  *      check whereClause
513  *
514  *  return value is counter of rewriting query
515  *  if return value is zero, all whereclause can insert dblink function.
516  */
517 static int
518 CheckWhereCaluse(Node *BaseSelect,RewriteQuery *message,ConInfoTodblink *dblink,String *str,int true_count)
519 {
520         A_Expr *expr = NULL;
521
522         if(!IsA(BaseSelect, A_Expr))
523         {
524                 delay_string_append_char(message, str, "TRUE");
525                 true_count++;
526                 return true_count;
527         }
528
529         expr = (A_Expr *) BaseSelect;
530
531         if(expr->kind == AEXPR_NOT)
532         {
533                 delay_string_append_char(message, str, "TRUE");
534                 true_count++;
535                 return true_count;
536         }
537         true_count = _writewhereClause(expr,message,dblink,str,true_count);
538         return true_count;
539 }
540
541 static void _rewriteIdList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *node)
542 {
543         ListCell   *lc;
544         char first = 0;
545
546         foreach(lc, node)
547         {
548                 Value *v = lfirst(lc);
549
550                 if (first == 0)
551                         first = 1;
552                 else
553                         delay_string_append_char(message, str, ", ");
554
555                 delay_string_append_char(message, str, "\"");
556                 delay_string_append_char(message, str, v->val.str);
557                 delay_string_append_char(message, str, "\"");
558         }
559 }
560
561 static void _rewriteList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *node)
562 {
563         ListCell   *lc;
564         char first = 0;
565         char state = (char)0;
566         int loop = 0;
567         bool from;
568         int current_select = message->current_select;
569         int next = -1;
570         bool lock = false;
571         AnalyzeSelect *analyze;
572
573         analyze = message->analyze[current_select];
574
575         if(message->r_code == SELECT_DEFAULT && message->ignore_rewrite == -1 &&
576                                 analyze->part == SELECT_TARGETLIST)
577         {
578                 if(analyze->retlock == false)
579                 {
580                         lock = true;
581                         analyze->retlock = true;
582                 }
583         }
584
585         foreach(lc, node)
586         {
587                 next = message->analyze_num;
588                 if (first == 0)
589                 {
590                         first = 1;
591                 }
592                 else
593                 {
594                         if(lfirst(lc) && !IsA(lfirst(lc),A_Indices))
595                                 delay_string_append_char(message, str, ",");
596                 }
597
598                 /* init JoinTable */
599                 if(message->r_code == SELECT_ANALYZE && message->fromClause)
600                 {
601                         if(lfirst(lc) && IsA(lfirst(lc),JoinExpr))
602                         {
603                                 if(!analyze->join)
604                                 {
605                                         analyze->join = (JoinTable *) palloc(sizeof(JoinTable));
606                                 }
607                                 analyze->join->col_num = 0;
608                                 analyze->join->col_list = NULL;
609                                 analyze->join->type_list = NULL;
610                                 analyze->join->table_list = NULL;
611                                 analyze->join->using_list = NULL;
612                                 analyze->join->using_length = 0;
613                                 analyze->join->state = (char)0;
614                         }
615                 }
616
617                 from = message->fromClause;
618                 _rewriteNode(BaseSelect, message, dblink, str, lfirst(lc));
619                 message->current_select = current_select;
620                 message->fromClause = from;
621
622                 if(message->r_code == SELECT_ANALYZE && message->fromClause)
623                 {
624                         /*
625                         if(lfirst(lc))
626                         { 
627                                 if(IsA(lfirst(lc),JoinExpr))
628                                 {
629                                         JoinExpr *join = lfirst(lc);
630                                         if (join->quals)
631                                         {
632                                                 _rewriteNode(BaseSelect, message, dblink, str, join->quals);
633                                         }
634                                 }
635                         }
636                         */
637
638                         if(loop == 0)
639                         {
640                                 state = message->table_state;
641                         }
642                         else
643                         {
644                                 if(state =='L' && message->table_state == 'L')
645                                 {
646                                         message->table_state = 'L';
647                                 }
648                                 else if (state == 'L' && message->table_state == 'P')
649                                 {
650                                         message->table_state = 'P';
651                                 }
652                                 else if (state == 'P' && message->table_state == 'L')
653                                 {
654                                         message->table_state = 'P';
655                                 }
656                                 else
657                                 {
658                                         state = 'S';
659                                         message->table_state = 'S';
660                                 }
661                         }
662                 }
663                 loop++;
664
665                 if(message->r_code == SELECT_DEFAULT && message->ignore_rewrite == -1 &&
666                                  analyze->part == SELECT_TARGETLIST)
667                 {
668                         pool_debug("_rewriteList select=%d,count=%d", current_select,message->analyze[current_select]->ret_count);
669                         if(lock)
670                                 message->analyze[current_select]->ret_count++;
671                 }
672         }
673
674         if(message->r_code == SELECT_DEFAULT && message->ignore_rewrite == -1 &&
675                                 analyze->part == SELECT_TARGETLIST)
676         {
677                 if(analyze->retlock && lock)
678                 {
679                         analyze->retlock = false;
680                 }
681         }
682 }
683
684
685 /*****************************************************************************
686  *
687  *      Stuff from primnodes.h.
688  *
689  *****************************************************************************/
690
691 static void
692 _rewriteAlias(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Alias *node)
693 {
694         delay_string_append_char(message, str, " AS ");
695         delay_string_append_char(message, str, node->aliasname);
696         delay_string_append_char(message, str, " ");
697
698         if (node->colnames)
699         {
700                 delay_string_append_char(message, str, "(");
701                 _rewriteNode(BaseSelect, message, dblink, str, node->colnames);
702                 delay_string_append_char(message, str, ")");
703         }
704 }
705
706 static void
707 append_all_virtual(AnalyzeSelect *analyze,char *table)
708 {
709         VirtualTable *virtual;
710         SelectDefInfo *select_ret;
711         int num;
712         int test_num;
713         int base;
714         int i;
715         int counter = 0;
716
717         virtual = analyze->virtual;
718         test_num = virtual->col_num;
719         select_ret = analyze->select_ret;
720         base = select_ret->col_num;
721
722         if(!table)
723         {
724                 num = test_num;
725         }
726         else
727         {
728                 num = 0;
729                 for(i = 0; i< test_num; i++)
730                 {
731                         if(!strcmp(virtual->table_list[i],table))
732                                 num++;
733                 }
734         }
735
736         if(base == 0)
737         {
738                 select_ret->col_list = (char **) palloc(num * sizeof(char *));
739                 select_ret->type_list = (char **) palloc(num * sizeof(char *));
740                 select_ret->return_list = (int *) palloc(num * sizeof(int));
741         }
742         else
743         {
744                 select_ret->col_list = (char **) repalloc(select_ret->col_list,(base + num) * sizeof(char *));
745                 select_ret->type_list = (char **) repalloc(select_ret->type_list,(base + num) * sizeof(char *));
746                 select_ret->return_list = (int *) repalloc(select_ret->return_list,(base + num) * sizeof(int));
747         }
748
749         for(i = 0; i< test_num;i++)
750         {
751                 if(table && strcmp(virtual->table_list[i],table))
752                 {
753                         continue;
754                 }
755                 select_ret->col_list[base + counter]  = virtual->col_list[i];
756                 select_ret->type_list[base + counter] = virtual->type_list[i];  
757                 select_ret->return_list[base + counter] = -1;   
758                 pool_debug("append_all_virtual: analyze[%d] col=%s,type=%s", analyze->now_select,
759                 select_ret->col_list[base + counter],select_ret->type_list[base + counter]);
760                 counter++;
761         }
762         select_ret->col_num = base + num;
763 }
764
765 static void
766 append_select_def_info(SelectDefInfo *select_ret,char *col,char *type)
767 {
768         int base;
769
770         base  = select_ret->col_num;
771         pool_debug("append_select_def_info: base=%d",base);
772
773         if(!type)
774         {
775                 type = (char *)palloc(sizeof(char) * strlen("text") + 1);
776                 strcpy(type,"text");
777         }
778
779         if(base == 0)
780         {
781                 select_ret->col_list = (char **) palloc(sizeof(char *));
782                 select_ret->type_list = (char **) palloc(sizeof(char *));
783                 select_ret->return_list = (int *) palloc(sizeof(int));
784         }
785         else
786         {
787                 select_ret->col_list = (char **) repalloc(select_ret->col_list,(base + 1) * sizeof(char *));
788                 select_ret->type_list = (char **) repalloc(select_ret->type_list,(base + 1) * sizeof(char *));
789                 select_ret->return_list = (int *) repalloc(select_ret->return_list,(base + 1) * sizeof(int));
790         }
791
792         select_ret->col_list[base] = col;
793         select_ret->type_list[base] = type;
794         select_ret->return_list[base] = -1;
795
796         select_ret->col_num++;
797         pool_debug("append_select_def_info: col=%s,type=%s base=%d",
798                                                         select_ret->col_list[base],select_ret->type_list[base],select_ret->col_num);
799 }
800
801 static char *search_type_from_virtual(VirtualTable *virtual,char *table,char *col)
802 {
803         int num = virtual->col_num;
804         int i;
805
806         for(i = 0; i < num; i++)
807         {
808                 if(table)
809                 {
810                         if(!strcmp(virtual->table_list[i],table)
811                                         && !strcmp(virtual->col_list[i],col))
812                                 return virtual->type_list[i];
813                 }
814                 else
815                 {
816                         if(!strcmp(virtual->col_list[i],col))
817                                 return virtual->type_list[i];
818                 }
819         }
820         return NULL;
821 }
822
823
824 static void
825 AnalyzeReturnRecord(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *list)
826 {
827         int select_num;
828         int range_num;
829         AnalyzeSelect *analyze;
830         RangeInfo **range;
831         VirtualTable *virtual;
832         ListCell   *lc;
833         int n_sublink = 0;
834         int c_sublink = 0;
835
836         select_num = message->current_select;
837
838         analyze=message->analyze[select_num];
839
840         virtual = analyze->virtual;
841
842   /* get range table info */
843         range_num = analyze->rangeinfo_num;
844
845         /* "range = 0" means that this select stmt have no table */
846         range = analyze->range;
847
848         analyze->select_ret = (SelectDefInfo *) palloc(sizeof(SelectDefInfo));
849
850         analyze->select_ret->valid = false;
851         analyze->select_ret->col_num = 0;
852
853         pool_debug("AnalyzeReturnRecord: current_select=%d",select_num);
854
855         foreach(lc, list)
856         {
857                 ResTarget *target = NULL;
858                 Node *n = lfirst(lc);
859                 void *obj;
860                 char *alias = NULL;
861                 char *typecast = NULL;
862                 char *colname = NULL;
863                 char *table_name = NULL;
864                 char *gettype = NULL;
865
866                 target = (ResTarget *) n;
867
868                 /* alias name */
869                 if(target->name)
870                         alias = target->name;
871
872     /* type name */
873                 if(IsA(target->val, TypeCast))
874                 {
875                         TypeCast *type = (TypeCast *) target->val;
876                         TypeName *typename = (TypeName *)type->typename;
877                         obj = type->arg;
878                         typecast = strVal(lfirst(list_head(typename->names)));
879                 } else {
880                         obj = target->val;
881                 }
882                 if(typecast && alias)
883                 {
884                         append_select_def_info(analyze->select_ret,alias,typecast);
885                         continue;
886                 }
887
888     /* column name */
889                 if (obj && (IsA(obj, ColumnRef)))
890                 {
891                         int first = 0;
892                         ListCell *c;
893                         ColumnRef *col = NULL;
894
895                         col = (ColumnRef *) obj;
896                         foreach (c, col->fields)
897                         {
898                                 Node *n = (Node *) lfirst(c);
899
900                                 if (IsA(n, String))
901                                 {
902                                         Value *v = (Value *) lfirst(c);
903                                         if(col->fields->length == 2 && first == 0)
904                                         {
905                                                 first = 1;
906                                                 table_name = v->val.str;
907                                         }
908                                         else
909                                                 colname = v->val.str;
910                                 }
911                         }
912                 }
913                 else if(obj && (IsA(obj, A_Expr)))
914                 {
915                         if(alias)
916                                 append_select_def_info(analyze->select_ret,alias,typecast);
917                         else
918                         {
919                                 char *colname;
920                                 colname = (char *)palloc(sizeof(char) * strlen("\"?column?\"") + 1);
921                                 strcpy(colname,"\"?column?\"");
922                                 append_select_def_info(analyze->select_ret,colname,typecast);
923                         }
924                         continue;
925                 }
926                 else if(obj && (IsA(obj, FuncCall)))
927                 {
928                         if(alias)
929                         {
930                                 append_select_def_info(analyze->select_ret,alias,typecast);
931                         }
932                         else
933                         {
934                                 FuncCall *func = NULL;
935                                 char *funcname;
936                                 func = (FuncCall *) obj;
937                                 funcname = strVal(lfirst(list_head(func->funcname)));
938                                 append_select_def_info(analyze->select_ret,funcname,typecast);
939                         }
940                         continue;
941                 }
942                 else if (obj && (IsA(obj,SubLink)))
943                 {
944                         int i;
945                         int max = message->analyze_num;
946                         AnalyzeSelect *sublink = NULL;
947
948                         for(i = select_num + 1; i < max;i++)
949                         {
950                                 sublink = message->analyze[i];
951
952                                 if(sublink->last_select == select_num
953                                                 && sublink->part == 1 && c_sublink == n_sublink)
954                                         break;
955                         }
956
957                         n_sublink++;
958                         if(sublink && (sublink->select_ret->col_num == 1))
959                         {
960                                 if(alias)
961                                 {
962                                         append_select_def_info(analyze->select_ret,alias,sublink->select_ret->type_list[0]);
963                                         continue;
964                                 }
965                                 else
966                                 {
967                                         char *column;
968                                         column = (char *)palloc(sizeof(char) * strlen("\"?column?\"") + 1);
969                                         strcpy(column,"\"?column?\"");
970                                         append_select_def_info(analyze->select_ret,column,sublink->select_ret->type_list[0]);
971                                         continue;
972                                 }
973                         }
974                 }
975                 else if(obj && (IsA(obj,A_Const)))
976                 {
977                         A_Const *cst = (A_Const *) obj;
978                         char *column = NULL;
979
980                         if(!typecast && cst->typename)
981                         {
982                                 Value *v = linitial(cst->typename->names);
983                                 typecast = v->val.str;
984                   } 
985
986                         if(!alias)
987                         {
988                                 column = (char *)palloc(sizeof(char) * strlen("\"?column?\"") + 1);
989                                 strcpy(column,"\"?column?\"");
990                                 alias = column;
991                         }
992
993                         append_select_def_info(analyze->select_ret,alias,typecast);
994                         continue;
995                 }
996
997                 if(colname && !strcmp(colname,"*"))
998                 {
999                         append_all_virtual(analyze,table_name);
1000                         continue;
1001                 }
1002
1003                 if(colname)
1004                         gettype = search_type_from_virtual(virtual,table_name,colname);
1005                 else
1006                 {
1007                         char *column = NULL;
1008                         column = (char *)palloc(sizeof(char) * strlen("\"?column?\"") + 1);
1009                         strcpy(column,"\"?column?\"");
1010                         append_select_def_info(analyze->select_ret,column,NULL);
1011                         continue;
1012                 }
1013
1014                 if(gettype)
1015                 {
1016                         char *t_n;
1017                         char *t_t;
1018
1019                         if(alias)
1020                                 t_n = alias;
1021                         else
1022                                 t_n = colname;
1023
1024                         if(typecast)
1025                                 t_t = typecast;
1026                         else
1027                                 t_t = gettype;
1028                         append_select_def_info(analyze->select_ret,t_n,t_t);
1029                 }
1030         }
1031 }
1032
1033 static void
1034 append_virtual_table(RewriteQuery *message,VirtualTable *virtual,char **col_list,char **type_list,int col_num,char *table_name,char state,int next)
1035 {
1036         int base;
1037         int i;
1038
1039         if(virtual->col_num == 0)
1040         {
1041                 base = 0;
1042                 virtual->col_list   = (char**) palloc(sizeof(char*) * col_num);
1043                 virtual->type_list  = (char**) palloc(sizeof(char*) * col_num);
1044                 virtual->table_list = (char**) palloc(sizeof(char*) * col_num);
1045                 virtual->state_list = (char*)  palloc(sizeof(char) * col_num);
1046                 virtual->column_no  = (int*)   palloc(sizeof(int) * col_num);
1047                 virtual->valid      = (int*)   palloc(sizeof(int) * col_num);
1048         }
1049         else
1050   {
1051                 base = virtual->col_num;
1052                 virtual->col_list   = (char**) repalloc(virtual->col_list,sizeof(char*)  * (base + col_num));
1053                 virtual->type_list  = (char**) repalloc(virtual->type_list,sizeof(char*) * (base + col_num));
1054                 virtual->table_list = (char**) repalloc(virtual->table_list,sizeof(char*)* (base + col_num));
1055                 virtual->state_list = (char*)  repalloc(virtual->state_list,sizeof(char) * (base + col_num));
1056                 virtual->column_no  = (int*)   repalloc(virtual->column_no,sizeof(int) * (base + col_num));
1057                 virtual->valid      = (int*)   repalloc(virtual->valid,sizeof(int) * (base + col_num));
1058         }
1059
1060         for(i = 0; i< col_num; i++)
1061         {
1062                 int j = base + i;
1063
1064                 virtual->col_list[j]   = col_list[i];
1065                 virtual->type_list[j]  = type_list[i];
1066                 virtual->table_list[j] = table_name;
1067                 virtual->state_list[j] = state;
1068
1069                 /* (next > 0) means this function call from RangeSubselect */
1070                 if(next > 0)
1071                 {
1072                         AnalyzeSelect *analyze = message->analyze[next];
1073                         SelectDefInfo *select_ret;
1074                         select_ret = analyze->select_ret;
1075                         select_ret->return_list[i] = message->column;   
1076                         pool_debug("append_virtual_table return_list[%d]=%d,analyze[%d]",i,message->column,next);
1077                 }
1078                 virtual->column_no[j] = message->column;
1079                 message->column++;
1080                 virtual->valid[j] = -1;
1081                 pool_debug("append_virtual_table select=%d, no=%d,col=%s,type=%s,table=%s,state=%c,valid=%d",
1082                         message->current_select,
1083                         virtual->column_no[j],virtual->col_list[j],virtual->type_list[j]
1084                         ,virtual->table_list[j],virtual->state_list[j],virtual->valid[j]);
1085         }
1086         virtual->col_num = base + col_num;
1087 }
1088
1089
1090 static void append_join_using(AnalyzeSelect *analyze,char **col_list,char **type_list,int col_num,char *table_name)
1091 {
1092         int num,i,j,k;
1093         int same[analyze->join->col_num];
1094         int lvalid[analyze->join->col_num];
1095         int rvalid[col_num];
1096         char **using;
1097         int lc = 0;
1098         int rc = 0;
1099         int sc = 0;
1100         int total;
1101         JoinTable *join = analyze->join;
1102         JoinTable *new = (JoinTable *) palloc(sizeof(JoinTable));
1103
1104         using = join->using_list;
1105         num = join->using_length;
1106
1107         for(i = 0; i < join->col_num; i++)
1108         {
1109                 char *colname = join->col_list[i];
1110                 for(j = 0; j < num; j++)
1111                 {
1112                         if(!strcmp(colname, using[j]))
1113                         {
1114                                 same[sc] = i;
1115                                 sc++;
1116                         } else {
1117                                 lvalid[lc] = i;
1118                                 lc++;
1119                         }
1120                 }
1121         }
1122
1123
1124         for(i = 0; i < col_num; i++)
1125         {
1126                 char *colname = col_list[i];
1127                 for(j = 0; j < num; j++)
1128                 {
1129                         if(strcmp(colname, using[j]))
1130                         {
1131                                 rvalid[rc] = i;
1132                                 rc++;
1133                         }
1134                 }
1135         }
1136
1137         total= sc + lc + rc;
1138         new->col_num = total;
1139         new->col_list = (char**) palloc(sizeof(char*) * (total));
1140         new->type_list = (char**) palloc(sizeof(char*) * (total));
1141         new->table_list = (char**) palloc(sizeof(char*) * (total));
1142
1143         for(k = 0; k < sc; k++)
1144         {
1145                 new->col_list[k] = join->col_list[same[k]];
1146                 new->type_list[k] = join->type_list[same[k]];
1147                 new->table_list[k] = join->table_list[same[k]];
1148         }
1149
1150         for(k = sc; k < sc + lc; k++)
1151         {
1152                 new->col_list[k] = join->col_list[lvalid[k - sc]];
1153                 new->type_list[k] = join->type_list[lvalid[k - sc]];
1154                 new->table_list[k] = join->table_list[lvalid[k - sc]];
1155         }
1156         for(k = sc + lc; k < sc + lc + rc; k++)
1157         {
1158                 new->col_list[k] = col_list[rvalid[k - lc - sc]];
1159                 new->type_list[k] = type_list[rvalid[k - lc - sc]];
1160                 if(table_name)
1161                 {
1162                         new->table_list[k] = table_name;
1163                 }
1164                 else
1165                         new->table_list[k] = NULL;
1166         }
1167
1168         analyze->join = new;
1169
1170         for(i = 0; i< analyze->join->col_num; i++)
1171         {
1172                 pool_debug("append_join_using no = %d ,col=%s,type=%s,table=%s",
1173                         i,new->col_list[i],new->type_list[i],new->table_list[i]);
1174         }
1175 }
1176
1177 static void append_join_natural(AnalyzeSelect *analyze,char **col_list,char **type_list,int base,int col_num,char *table_name)
1178 {
1179         int same[base + 1];
1180         int rvalid[base + 1];
1181         int linvalid[col_num + 1];
1182         int lvalid[col_num +1];
1183         int i,j,k;
1184         int sc = 0;
1185         int vc = 0;
1186         int ic = 0;
1187         int total = 0;
1188         int count;
1189         JoinTable *join = analyze->join;
1190         JoinTable *new = (JoinTable *) palloc(sizeof(JoinTable));
1191
1192         for(i = 0; i < base; i++)
1193         {
1194                 char *colname = join->col_list[i];
1195                 int match  = 0;
1196                 int array = -1;
1197                 for(j = 0; j < col_num; j++)
1198                 {
1199                         if(!strcmp(colname, col_list[j]))
1200                         {
1201                                 match++;
1202                                 array = j;
1203                         }
1204                 }
1205
1206                 if(match == 0)
1207                 {
1208                         rvalid[vc] = i;
1209                         vc++;
1210                 }
1211                 else if(match == 1)
1212                 {
1213                         same[sc] = i;
1214                         linvalid[ic] = array;
1215                         sc++;
1216                         ic++;
1217                 }
1218                 else
1219                 {
1220                         /* XXX */
1221                 }
1222         }
1223
1224         total=sc + vc + (col_num - ic);
1225         new->col_num = total;
1226         new->col_list = (char**) palloc(sizeof(char*) * (total));
1227         new->type_list = (char**) palloc(sizeof(char*) * (total));
1228         new->table_list = (char**) palloc(sizeof(char*) * (total));
1229
1230         for(k = 0; k < sc; k++)
1231         {
1232                 new->col_list[k] = join->col_list[same[k]];
1233                 new->type_list[k] = join->type_list[same[k]];
1234                 if(table_name)
1235                 {
1236                         new->table_list[k] = table_name;
1237                 }
1238                 else
1239                         new->table_list[k] = join->table_list[same[k]];
1240         }
1241
1242         for(k = sc; k < sc + vc; k++)
1243         {
1244                 new->col_list[k] = join->col_list[rvalid[k - sc]];
1245                 new->type_list[k] = join->type_list[rvalid[k - sc]];
1246                 if(table_name)
1247                 {
1248                         new->table_list[k] = table_name;
1249                 }
1250                 else
1251                         new->table_list[k] = join->table_list[rvalid[k - sc]];
1252         }
1253
1254         count = 0;
1255         for(k = 0; k <col_num ; k++)
1256         {
1257                 int l = 0;
1258                 bool test = true;
1259                 for(l = 0; l< ic; l++)
1260                 {
1261                         if(k == linvalid[l])
1262                                 test = false;
1263                 }
1264                 if(test)
1265                 {
1266                         lvalid[count] = k;
1267                         count++;
1268                 }
1269         }
1270
1271         for(k = sc + vc; k < sc + vc + count; k++)
1272         {
1273                 new->col_list[k] = col_list[lvalid[k - sc - vc]];
1274                 new->type_list[k] = type_list[lvalid[k - sc - vc]];
1275                 if(table_name)
1276                 {
1277                         new->table_list[k] = table_name;
1278                 }
1279                 else
1280                         new->table_list[k] = NULL;
1281         }
1282         analyze->join = new;
1283
1284         for(i = 0; i< analyze->join->col_num; i++)
1285         {
1286                 pool_debug("append_join_natural no = %d ,col=%s,type=%s,table=%s",
1287                         i,new->col_list[i],new->type_list[i],new->table_list[i]);
1288         }
1289 }
1290
1291 static void append_join_simple(JoinTable *join,char **col_list,char **type_list,int col_num,char *table_name)
1292 {
1293         int base;
1294         int i;
1295         pool_debug("append_join_table start");
1296
1297         if(join->col_num == 0)
1298         {
1299                 base = 0;
1300                 join->col_list = (char**) palloc(sizeof(char*) * col_num);
1301                 join->type_list = (char**) palloc(sizeof(char*) * col_num);
1302                 join->table_list = (char**) palloc(sizeof(char*) * col_num);
1303         }
1304         else
1305         {
1306                 base = join->col_num;
1307                 join->col_list = (char**) repalloc(join->col_list,sizeof(char*) * (base + col_num));
1308                 join->type_list = (char**) repalloc(join->type_list,sizeof(char*) * (base + col_num));
1309                 join->table_list = (char**) repalloc(join->table_list,sizeof(char*) * (base + col_num));
1310         }
1311
1312         for(i = 0; i< col_num; i++)
1313         {
1314                 join->col_list[base + i] = col_list[i];
1315                 join->type_list[base + i] = type_list[i];
1316                 join->table_list[base + i] = table_name;
1317                 pool_debug("append_join_table no = %d ,col=%s,type=%s,table=%s",
1318                         base + i,join->col_list[base + i],join->type_list[base + i],join->table_list[base + i]);
1319         }
1320         join->col_num = base + col_num;
1321 }
1322
1323 static void build_join_table(RewriteQuery *message,char *alias, int type)
1324 {
1325         char *table_name = NULL;
1326         char state;
1327         char lstate;
1328         int left_num,right_num,range_num,select_num;
1329         DistDefInfo *distinfo = NULL;
1330         RepliDefInfo *repliinfo = NULL;
1331         SelectDefInfo *selectinfo = NULL;
1332         JoinTable *join;
1333         RangeInfo *range;
1334         AnalyzeSelect *analyze;
1335
1336         select_num = message->current_select;
1337         analyze=message->analyze[select_num];
1338         join = analyze->join;
1339         left_num = join->col_num;
1340         range_num = analyze->rangeinfo_num;
1341         range = analyze->range[range_num - 1];
1342         state = range->state;
1343         lstate = join->state;
1344         right_num = 0;
1345
1346         distinfo = range->distinfo;
1347         repliinfo = range->repliinfo;
1348         selectinfo = range->selectinfo;
1349
1350         if(alias)
1351                 table_name = alias;
1352         else if(!alias && range->alias)
1353                 table_name = range->alias;
1354                                 
1355         if(distinfo && !repliinfo && !selectinfo)
1356         {
1357                 right_num = distinfo->col_num;
1358                 if(!table_name)
1359                         table_name = distinfo->table_name;
1360                 pool_debug("inside build_join_info dist state=%c  %s",range->state,table_name);
1361
1362                 if(type == JNATURAL_INNER || type == JNATURAL_RIGHT
1363                   || type == JNATURAL_LEFT || type == JNATURAL_FULL)
1364                         append_join_natural(analyze,distinfo->col_list,distinfo->type_list,join->col_num,distinfo->col_num,table_name);
1365                 else
1366                         append_join_simple(join,distinfo->col_list,distinfo->type_list,distinfo->col_num,table_name);
1367         }
1368         else if (repliinfo && !distinfo && !selectinfo)
1369         {
1370                 right_num = repliinfo->col_num;
1371                 if(!table_name)
1372                         table_name = repliinfo->table_name;
1373
1374                 pool_debug("inside build_join_info repli state=%c %s",range->state,table_name);
1375
1376                 if(type == JNATURAL_INNER || type == JNATURAL_RIGHT
1377                   || type == JNATURAL_LEFT || type == JNATURAL_FULL)
1378                         append_join_natural(analyze,repliinfo->col_list,repliinfo->type_list,join->col_num,repliinfo->col_num,table_name);
1379                 else if(join->using_length != 0)
1380                         append_join_using(analyze,repliinfo->col_list,repliinfo->type_list,repliinfo->col_num,table_name);
1381                 else
1382                         append_join_simple(join,repliinfo->col_list,repliinfo->type_list,repliinfo->col_num,table_name);
1383         }
1384         else if (selectinfo && !repliinfo && !distinfo)
1385         {
1386                 pool_debug("inside build_join_info select state=%c %s",range->state,table_name);
1387                 right_num = selectinfo->col_num;
1388
1389                 if(type == JNATURAL_INNER || type == JNATURAL_RIGHT
1390                   || type == JNATURAL_LEFT || type == JNATURAL_FULL)
1391                         append_join_natural(analyze,selectinfo->col_list,selectinfo->type_list,join->col_num,selectinfo->col_num,table_name);
1392                 else if(join->using_length != 0)
1393                         append_join_using(analyze,selectinfo->col_list,selectinfo->type_list,selectinfo->col_num,table_name);
1394                 else
1395                         append_join_simple(join,selectinfo->col_list,selectinfo->type_list,selectinfo->col_num,table_name);
1396         }
1397
1398         if(type == JDEFAULT)
1399         {
1400                 join->state = state;
1401                 return;
1402         }
1403
1404         join =analyze->join;
1405
1406         if(lstate =='E' || state == 'E')
1407         {
1408                 join->state = 'E';
1409                 return;
1410         }
1411         if(lstate =='L' && state =='L')
1412         {
1413                 join->state = 'L';
1414                 return;
1415         }
1416         if(lstate =='L' && state =='P')
1417         {
1418                 int total = left_num + right_num;
1419                 if(type == JRIGHT || type == JNORMAL || type == JINNER || type == JNATURAL_INNER)
1420                         join->state = 'P';
1421                 else if((join->col_num <= total) && (type == JNATURAL_RIGHT))
1422                         join->state = 'P';
1423                 else if((join->col_num == total) && (type == JNATURAL_LEFT))
1424                         join->state = 'P';
1425                 else
1426                         join->state = 'S';
1427         } 
1428         else if(lstate =='P' && state == 'L')
1429         {
1430                 int total = left_num + right_num;
1431                 if(type == JLEFT || type == JNORMAL || type == JINNER || type == JNATURAL_INNER)
1432                         join->state ='P';
1433                 else if((join->col_num <= total) && (type == JNATURAL_LEFT))
1434                         join->state = 'P';
1435                 else if((join->col_num == total) && (type == JNATURAL_RIGHT))
1436                         join->state = 'P';
1437                 else
1438                         join->state ='S';
1439         }
1440         else
1441                 join->state = 'S';
1442 }
1443
1444 static void change_analyze_state(AnalyzeSelect *analyze,char state)
1445 {
1446         if(state == 'E' || analyze->state == 'E')
1447                 return;
1448
1449         if(!analyze->state)
1450         {
1451                 analyze->state = state;
1452         }
1453         else if(analyze->state == 'P' && state =='L')
1454         {
1455                 analyze->state = 'P';
1456         }
1457         else if(analyze->state == 'L' && state =='P')
1458         {
1459                 analyze->state = 'P';
1460         }
1461         else if(analyze->state == 'L' && state =='L')
1462         {
1463                         return;
1464         }
1465         else
1466                 analyze->state = 'S';
1467 }
1468
1469 static void build_virtual_table(RewriteQuery *message,void *obj,int next)
1470 {
1471         int select_num;
1472         int range_num;
1473         char *alias = NULL;
1474         char *table_name = NULL;
1475         char state;
1476         AnalyzeSelect *analyze;
1477         VirtualTable *virtual;
1478         RangeInfo *range;
1479         DistDefInfo *distinfo;
1480         RepliDefInfo *repliinfo;
1481         SelectDefInfo *selectinfo;
1482
1483         select_num = message->current_select;
1484         analyze=message->analyze[select_num];
1485         virtual = analyze->virtual;             
1486
1487         /* last range */
1488         range_num = analyze->rangeinfo_num;
1489         range = analyze->range[range_num - 1];
1490         distinfo = range->distinfo;             
1491         repliinfo = range->repliinfo;
1492         selectinfo = range->selectinfo;
1493
1494         if(range->alias)
1495                 alias = range->alias;
1496
1497         state = range->state;
1498
1499         if(distinfo && !repliinfo && !selectinfo)
1500         {
1501                 if(alias)
1502                         table_name =alias;
1503                 else
1504                         table_name = distinfo->table_name;
1505
1506                 pool_debug("inside build_virtual_info dist state=%c  %s",range->state,table_name);
1507                 append_virtual_table(message,virtual,distinfo->col_list,distinfo->type_list,distinfo->col_num,table_name,state,-2);
1508                 change_analyze_state(analyze,state);
1509                 return;
1510         }
1511         else if (repliinfo && !distinfo && !selectinfo)
1512         {
1513                 if(alias)
1514                         table_name =alias;
1515                 else
1516                         table_name = repliinfo->table_name;
1517                 pool_debug("inside build_virtual_info repli state=%c %s",range->state,table_name);
1518                 append_virtual_table(message,virtual,repliinfo->col_list,repliinfo->type_list,repliinfo->col_num,table_name,state,-3);
1519                 change_analyze_state(analyze,state);
1520                 return;
1521         }
1522         else if (selectinfo && !repliinfo       && !distinfo)
1523         {
1524                 table_name = alias;
1525                 pool_debug("inside build_virtual_info select state=%c %s",range->state,table_name);
1526                 append_virtual_table(message,virtual,selectinfo->col_list,selectinfo->type_list,selectinfo->col_num,table_name,state,next);
1527                 change_analyze_state(analyze,state);
1528                 return;
1529         }
1530         else if (!selectinfo && !repliinfo      && !distinfo)
1531         {
1532                 pool_debug("inside build_virtual_info no dist state=%c %s",range->state,alias);
1533                 change_analyze_state(analyze,'E');
1534         }
1535 }
1536
1537 static void
1538 build_range_info(RewriteQuery *message,DistDefInfo *info,RepliDefInfo *info2,SelectDefInfo *info3,char *alias, int select_num,int i_num)
1539 {
1540         int num;
1541         AnalyzeSelect *analyze;
1542
1543         analyze=message->analyze[select_num];
1544
1545         if(analyze->range)
1546         {
1547                 ++analyze->rangeinfo_num;
1548                 num = analyze->rangeinfo_num;
1549                 analyze->range =
1550                                                         (RangeInfo **) repalloc(analyze->range,sizeof(RangeInfo *) * num);
1551
1552                 analyze->range[num-1] = (RangeInfo *) palloc(sizeof(RangeInfo));
1553                 pool_debug("inside build_range_info num= %d current_select=%d",num,select_num);
1554         }
1555         else
1556         {
1557                 num = 1;
1558                 analyze->range = (RangeInfo **) palloc(sizeof(RangeInfo *));
1559                 analyze->range[0] = (RangeInfo *) palloc(sizeof(RangeInfo));
1560                 analyze->rangeinfo_num = 1;
1561                 pool_debug("inside build_range_info num= %d current_select=%d",num,select_num);
1562         }
1563
1564         analyze->range[num -1]->ret_num = num - 1;
1565         analyze->range[num -1]->selectinfo = NULL;
1566         /* set dist_def_info */
1567         if(info && !info2 && !info3)
1568         {
1569                 message->is_loadbalance = false;
1570                 analyze->range[num -1]->distinfo = info;
1571                 analyze->range[num -1]->repliinfo = NULL;
1572                 analyze->select_ret = NULL;
1573                 analyze->range[num -1]->alias = alias;
1574                 analyze->range[num -1]->state = 'P';
1575                 pool_debug("inside build_range_info dist %d",select_num);
1576         }
1577
1578         /* set repli_def_info */
1579         if(info2 && !info && !info3)
1580         {
1581                 analyze->range[num -1]->distinfo = NULL;
1582                 analyze->range[num -1]->repliinfo = info2;
1583                 analyze->select_ret = NULL;
1584                 analyze->range[num -1]->alias = alias;
1585                 analyze->range[num -1]->state = 'L';
1586                 pool_debug("inside build_range_info repli %d",select_num);
1587                 return;
1588         }
1589
1590         /* CALL FROM _rertiteRangeSubselect */
1591         if(info3 && !info && !info2)
1592         {
1593                 char state = (char)0;
1594                 analyze->range[num -1]->distinfo = NULL;
1595                 analyze->range[num -1]->repliinfo = NULL;
1596                 analyze->range[num -1]->selectinfo = info3;
1597                 analyze->range[num -1]->alias = alias;
1598                 state = message->analyze[i_num]->state;
1599                 analyze->range[num -1]->state = state;
1600                 pool_debug("inside build_range_info select %d, state = %c (%c)",select_num,state,analyze->state);
1601                 return;
1602         }
1603
1604         if(info && info2)
1605         {
1606                 /*TODO: error*/
1607                 analyze->select_ret = NULL;
1608                 pool_debug("inside build_range_info error  %d",select_num);
1609                 return;
1610         }
1611
1612         if(!info && !info2 && !info3)
1613         {
1614                 /*TODO: error*/
1615                 message->is_loadbalance = true;
1616                 analyze->range[num -1]->distinfo = NULL;
1617                 analyze->range[num -1]->repliinfo = NULL;
1618                 analyze->range[num -1]->state = 'E';
1619                 analyze->select_ret = NULL;
1620                 analyze->range[num -1]->alias = alias;
1621                 pool_debug("inside build_range_info const or func  %d",select_num);
1622         }
1623 }
1624
1625 static void
1626 _rewriteRangeVar(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RangeVar *node)
1627 {
1628         DistDefInfo *info = NULL;
1629         RepliDefInfo *info2 = NULL;
1630
1631         if(message->r_code  == SELECT_ANALYZE)
1632         {
1633                 info = pool_get_dist_def_info(dblink->dbname, node->schemaname, node->relname);
1634                 info2 = pool_get_repli_def_info(dblink->dbname, node->schemaname, node->relname);
1635         }
1636
1637         if(!(message->r_code == SELECT_DEFAULT && message->rewritelock == -1 && message->ignore_rewrite == -1))
1638         {
1639                 if (node->catalogname)
1640                 {
1641                         delay_string_append_char(message, str, node->catalogname);
1642                         delay_string_append_char(message, str, ".");
1643                 }
1644
1645                 if (node->schemaname)
1646                 {
1647                         delay_string_append_char(message, str, node->schemaname);
1648                         delay_string_append_char(message, str, ".");
1649
1650                         if(strcmp(node->schemaname,"pg_catalog") == 0)
1651                         {
1652                                 message->is_pg_catalog = true;
1653                         }
1654                 }
1655
1656                 delay_string_append_char(message, str, node->relname);
1657
1658                 if (node->alias)
1659                 {
1660                         Alias *alias = node->alias;
1661                         _rewriteNode(BaseSelect, message, dblink, str, node->alias);
1662                         if(message->r_code == SELECT_ANALYZE)
1663                                 build_range_info(message,info,info2,NULL,alias->aliasname,message->current_select,-1);
1664                 }
1665                 else
1666                 {
1667                         if(message->r_code == SELECT_ANALYZE)
1668                                 build_range_info(message,info,info2,NULL,node->relname,message->current_select,-1);
1669                 }
1670
1671                 if (node->inhOpt == INH_YES)
1672                 {
1673                         delay_string_append_char(message, str, " * ");
1674                 }
1675
1676         }
1677         else
1678         {
1679                 /* rewrite query using dblink connection */
1680                 char *alias_name = NULL;
1681                 SelectStmt *select = (SelectStmt *)BaseSelect;
1682
1683                 if(node->alias)
1684                 {
1685                         alias_name = node->alias->aliasname;
1686                 }
1687                 /*
1688                  * iff schemaname is pg_catalog, send query to
1689                  * one node not system db.
1690                  */
1691                 if(node->schemaname &&
1692                         (strcmp(node->schemaname,"pg_catalog") == 0))
1693                 {
1694                         message->is_pg_catalog =true;
1695                         return;
1696                 }
1697
1698                 info = pool_get_dist_def_info(dblink->dbname, node->schemaname, node->relname);
1699                 info2 = pool_get_repli_def_info(dblink->dbname, node->schemaname, node->relname);
1700
1701                 writeRangeHeader(message,dblink,str,info,info2,alias_name);
1702
1703                 if (node->catalogname)
1704                 {
1705                         delay_string_append_char(message, str, node->catalogname);
1706                         delay_string_append_char(message, str, ".");
1707                 }
1708
1709                 if (node->schemaname)
1710                 {
1711                         delay_string_append_char(message, str, node->schemaname);
1712                         delay_string_append_char(message, str, ".");
1713                         message->schemaname = node->schemaname;
1714
1715                         if(strcmp(node->schemaname,"pg_catalog") == 0)
1716                         {
1717                                 message->is_pg_catalog = true;
1718                         }
1719
1720                 }
1721                 else
1722                         message->schemaname = NULL;
1723
1724                 delay_string_append_char(message, str, node->relname);
1725
1726                 if (alias_name)
1727                 {
1728                         delay_string_append_char(message, str, " AS ");
1729                         delay_string_append_char(message, str, alias_name);
1730                 }
1731
1732                 if(select->whereClause &&
1733                         !(message->r_code == SELECT_PGCATALOG))
1734                 {
1735                                 char * temp = NULL;
1736                                 int message_code = message->r_code;
1737                                 delay_string_append_char(message, str, " WHERE ");
1738
1739                                 if(message->table_relname)
1740                                         temp = message->table_relname;
1741
1742                                 if(alias_name)
1743                                         message->table_relname = alias_name;
1744                                 else
1745                                         message->table_relname = node->relname;
1746
1747                                 message->rewritelock = message->current_select;
1748                                 CheckWhereCaluse(select->whereClause, message,dblink,str,0);
1749                                 message->rewritelock = -1;
1750                                 message->table_relname = temp;
1751                                 KeepRewriteQueryReturnCode(message, message_code);
1752                 }
1753
1754                 writeRangeFooter(message,dblink,str,info,info2,alias_name);
1755
1756                 if (node->inhOpt == INH_YES)
1757                 {
1758                         delay_string_append_char(message, str, " * ");
1759                 }
1760         }
1761
1762         /*2009/07/27*/
1763         if(message->r_code == SELECT_ANALYZE && message->fromClause)
1764         {
1765                 int next = message->analyze_num;
1766                 build_virtual_table(message,node,next);
1767         }
1768 }
1769
1770 static void
1771 _rewriteVar(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Var *node)
1772 {
1773
1774 }
1775
1776 static void
1777 _rewriteConst(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Const *node)
1778 {
1779
1780 }
1781
1782 static void
1783 _rewriteParam(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Param *node)
1784 {
1785
1786 }
1787
1788 static void
1789 _rewriteAggref(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Aggref *node)
1790 {
1791
1792 }
1793
1794 static void
1795 _rewriteArrayRef(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ArrayRef *node)
1796 {
1797
1798 }
1799
1800 static void
1801 _rewriteFuncExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FuncExpr *node)
1802 {
1803
1804 }
1805
1806 static void
1807 _rewriteOpExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, OpExpr *node)
1808 {
1809
1810 }
1811
1812 static void
1813 _rewriteDistinctExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DistinctExpr *node)
1814 {
1815
1816 }
1817
1818 static void
1819 _rewriteScalarArrayOpExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ScalarArrayOpExpr *node)
1820 {
1821
1822 }
1823
1824 static void
1825 _rewriteBoolExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, BoolExpr *node)
1826 {
1827
1828 }
1829
1830 static void
1831 _rewriteSubLink(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SubLink *node)
1832 {
1833         if(message->r_code == SELECT_AEXPR)
1834         {
1835                 KeepRewriteQueryReturnCode(message, SELECT_AEXPR_FALSE);
1836                 return;
1837         }
1838         _rewriteNode(BaseSelect, message, dblink, str, node->testexpr);
1839
1840         if (node->operName != NIL)
1841         {
1842                 Value *v = linitial(node->operName);
1843                 if (strcmp(v->val.str, "=") == 0)
1844                         delay_string_append_char(message, str, " IN ");
1845                 else
1846                 {
1847                         delay_string_append_char(message, str, v->val.str);
1848                 }
1849         }
1850
1851         switch (node->subLinkType)
1852         {
1853                 case EXISTS_SUBLINK:
1854                         delay_string_append_char(message, str, " EXISTS ");
1855                         break;
1856
1857                 case ARRAY_SUBLINK:
1858                         delay_string_append_char(message, str, " ARRAY ");
1859                         break;
1860
1861                 case ANY_SUBLINK:
1862                         if (node->operName != NIL)
1863                         {
1864                                 Value *v = linitial(node->operName);
1865                                 if (strcmp(v->val.str, "=") != 0)
1866                                 {
1867                                         delay_string_append_char(message, str, v->val.str);
1868                                         delay_string_append_char(message, str, " ANY ");
1869                                 }
1870                         }
1871                         break;
1872
1873                 case ALL_SUBLINK:
1874                         delay_string_append_char(message, str, " ALL ");
1875                         break;
1876
1877                 default:
1878                         break;
1879         }
1880
1881         if (node->subselect)
1882         {
1883                 int count = message->current_select;
1884                 int part  = message->part;
1885                 delay_string_append_char(message, str, "(");
1886                 _rewriteNode(BaseSelect, message, dblink, str, node->subselect);
1887                 delay_string_append_char(message, str, ")");
1888                 KeepMessages(message,count,part);
1889         }
1890 }
1891
1892 static void
1893 _rewriteSubPlan(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SubPlan *node)
1894 {
1895
1896 }
1897
1898 static void
1899 _rewriteFieldSelect(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FieldSelect *node)
1900 {
1901
1902 }
1903
1904 static void
1905 _rewriteFieldStore(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FieldStore *node)
1906 {
1907
1908 }
1909
1910 static void
1911 _rewriteRelabelType(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RelabelType *node)
1912 {
1913
1914 }
1915
1916 static void
1917 _rewriteConvertRowtypeExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ConvertRowtypeExpr *node)
1918 {
1919
1920 }
1921
1922 static void
1923 _rewriteCaseExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CaseExpr *node)
1924 {
1925         ListCell *lc;
1926
1927         delay_string_append_char(message, str, "CASE ");
1928         if (node->arg)
1929                 _rewriteNode(BaseSelect, message, dblink, str, node->arg);
1930
1931         foreach (lc, node->args)
1932         {
1933                 _rewriteNode(BaseSelect, message, dblink, str, lfirst(lc));
1934         }
1935
1936         if (node->defresult)
1937         {
1938                 delay_string_append_char(message, str, " ELSE ");
1939                 _rewriteNode(BaseSelect, message, dblink, str, node->defresult);
1940         }
1941
1942         delay_string_append_char(message, str, " END");
1943 }
1944
1945 static void
1946 _rewriteCaseWhen(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CaseWhen *node)
1947 {
1948         delay_string_append_char(message, str, " WHEN ");
1949         _rewriteNode(BaseSelect, message, dblink, str, node->expr);
1950         delay_string_append_char(message, str, " THEN ");
1951         _rewriteNode(BaseSelect, message, dblink, str, node->result);
1952 }
1953
1954 static void
1955 _rewriteCaseTestExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CaseTestExpr *node)
1956 {
1957
1958 }
1959
1960 static void
1961 _rewriteArrayExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ArrayExpr *node)
1962 {
1963         delay_string_append_char(message, str, "[");
1964         _rewriteNode(BaseSelect, message, dblink, str, node->elements);
1965         delay_string_append_char(message, str, "]");
1966 }
1967
1968 static void
1969 _rewriteRowExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RowExpr *node)
1970 {
1971         if (node->args == NIL)
1972                 delay_string_append_char(message, str, "ROW ()");
1973         else
1974         {
1975                 delay_string_append_char(message, str, "ROW (");
1976                 _rewriteNode(BaseSelect, message, dblink, str, node->args);
1977                 delay_string_append_char(message, str, ")");
1978         }
1979 }
1980
1981 static void
1982 _rewriteCoalesceExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CoalesceExpr *node)
1983 {
1984         delay_string_append_char(message, str, "COALESCE (");
1985         _rewriteNode(BaseSelect, message, dblink, str, node->args);
1986         delay_string_append_char(message, str, ")");
1987 }
1988
1989 static void
1990 _rewriteMinMaxExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, MinMaxExpr *node)
1991 {
1992         if (node->op == IS_GREATEST)
1993         {
1994                 delay_string_append_char(message, str, "GREATEST (");
1995                 _rewriteNode(BaseSelect, message, dblink, str, node->args);
1996                 delay_string_append_char(message, str, ")");
1997         }
1998         else if (node->op == IS_LEAST)
1999         {
2000                 delay_string_append_char(message, str, "LEAST (");
2001                 _rewriteNode(BaseSelect, message, dblink, str, node->args);
2002                 delay_string_append_char(message, str, ")");
2003         }
2004 }
2005
2006 static void
2007 _rewriteNullIfExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, NullIfExpr *node)
2008 {
2009
2010 }
2011
2012 static void
2013 _rewriteNullTest(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, NullTest *node)
2014 {
2015         _rewriteNode(BaseSelect, message, dblink, str, node->arg);
2016         if (node->nulltesttype == IS_NOT_NULL)
2017                 delay_string_append_char(message, str, " IS NOT NULL");
2018         else
2019                 delay_string_append_char(message, str, " IS NULL");
2020 }
2021
2022 static void
2023 _rewriteBooleanTest(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, BooleanTest *node)
2024 {
2025         _rewriteNode(BaseSelect, message, dblink, str, node->arg);
2026
2027         switch (node->booltesttype)
2028         {
2029                 case IS_TRUE:
2030                         delay_string_append_char(message, str, " IS TRUE");
2031                         break;
2032
2033                 case IS_NOT_TRUE:
2034                         delay_string_append_char(message, str, " IS NOT TRUE");
2035                         break;
2036
2037                 case IS_FALSE:
2038                         delay_string_append_char(message, str, " IS FALSE");
2039                         break;
2040
2041                 case IS_NOT_FALSE:
2042                         delay_string_append_char(message, str, " IS NOT FALSE");
2043                         break;
2044
2045                 case IS_UNKNOWN:
2046                         delay_string_append_char(message, str, " IS UNKNOWN");
2047                         break;
2048
2049                 case IS_NOT_UNKNOWN:
2050                         delay_string_append_char(message, str, " IS NOT UNKNOWN");
2051                         break;
2052         }
2053 }
2054
2055 static void
2056 _rewriteCoerceToDomain(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CoerceToDomain *node)
2057 {
2058
2059 }
2060
2061 static void
2062 _rewriteCoerceToDomainValue(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CoerceToDomainValue *node)
2063 {
2064
2065 }
2066
2067 static void
2068 _rewriteSetToDefault(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SetToDefault *node)
2069 {
2070         delay_string_append_char(message, str, "DEFAULT");
2071 }
2072
2073 static void
2074 _rewriteTargetEntry(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, TargetEntry *node)
2075 {
2076
2077 }
2078
2079 static void
2080 _rewriteRangeTblRef(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RangeTblRef *node)
2081 {
2082
2083 }
2084
2085 static char *GetTableName(Node *node)
2086 {
2087
2088         if(IsA(node, RangeVar))
2089         {
2090                 RangeVar *range = (RangeVar *)node;
2091                 if(range->alias)
2092                 {
2093                         Alias *alias = range->alias;
2094                         return alias->aliasname;
2095                 } else {
2096                         return range->relname;
2097                 }
2098         }
2099         else if (IsA(node,RangeSubselect))
2100         {
2101                 RangeSubselect *select = (RangeSubselect *)node;
2102                 Alias * alias = select->alias;
2103                 return alias->aliasname;
2104         }
2105         return NULL;
2106 }
2107
2108 static int RetVirtualColumn(VirtualTable *virtual, char *tablename, char *colname)
2109 {
2110         int col_num = virtual->col_num;
2111         int i;
2112         for( i = 0; i < col_num; i++)
2113         {
2114                 if(strcmp(virtual->col_list[i], colname) == 0
2115                                 && strcmp(virtual->table_list[i], tablename) == 0)
2116                 {
2117                         return virtual->column_no[i];
2118                 }
2119         }
2120
2121         /* ERROR OR AMBIGIUS */
2122         return -1;
2123 }
2124
2125 static void
2126 ConvertFromUsingToON(RewriteQuery *message, String *str, JoinExpr *node, int select_num)
2127 {
2128         char *lname;
2129         char *rname;
2130         char comma = 0;
2131         ListCell *lc;
2132         VirtualTable *virtual = message->analyze[select_num]->virtual;
2133
2134         lname = GetTableName(node->larg);
2135         rname = GetTableName(node->rarg);
2136
2137         delay_string_append_char(message, str, " ON");
2138         foreach (lc, node->using)
2139         {
2140                 Value *value;
2141                 char lbuf[16];
2142                 char rbuf[16];
2143
2144                 if (comma == 0)
2145                         comma = 1;
2146                 else
2147                         delay_string_append_char(message, str, " AND ");
2148
2149                 value = lfirst(lc);
2150                 snprintf(lbuf, 16, "%d",RetVirtualColumn(virtual,lname,value->val.str));
2151                 snprintf(rbuf, 16, "%d",RetVirtualColumn(virtual,rname,value->val.str));
2152                 delay_string_append_char(message, str, " \"pool_c$");
2153                 delay_string_append_char(message, str, lbuf);
2154                 delay_string_append_char(message, str, "\"");
2155                 delay_string_append_char(message, str, " = ");
2156                 delay_string_append_char(message, str, "\"pool_c$");
2157                 delay_string_append_char(message, str, rbuf);
2158                 delay_string_append_char(message, str, "\"");
2159                 delay_string_append_char(message, str, " ");
2160         }
2161 }
2162
2163 static void
2164 _rewriteJoinExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, JoinExpr *node)
2165 {
2166         char l_state,r_state;
2167         bool from;
2168         int select_num;
2169         bool natural = false;
2170         bool inner   = false;
2171         bool cross   = false;
2172         bool full    = false;
2173         bool left    = false;
2174         bool right   = false;
2175         char *aliasname;
2176         int using_length = 0;
2177         char **using_list;
2178
2179         Alias *alias = node->alias;
2180         if(alias)
2181                 aliasname = alias->aliasname;
2182         else
2183                 aliasname = NULL;
2184
2185         from = message->fromClause;
2186         select_num = message->current_select;
2187
2188         _rewriteNode(BaseSelect, message, dblink, str, node->larg);
2189
2190         /* reset message */
2191         message->fromClause = from;
2192         message->current_select = select_num;
2193         l_state = message->table_state;
2194
2195         if(message->r_code == SELECT_ANALYZE &&
2196                         (IsA(node->larg, RangeVar) || IsA(node->larg,RangeSubselect)))
2197         {
2198                         build_join_table(message,aliasname,JDEFAULT);
2199         }
2200
2201
2202         if (node->isNatural == TRUE)
2203         {
2204                 natural = true;
2205                 delay_string_append_char(message, str, " NATURAL");
2206         }
2207
2208         if (node->jointype == JOIN_INNER)
2209         {
2210                 if (node->using == NIL && node->quals == NULL && !node->isNatural)
2211                 {
2212                         cross = true;
2213                         delay_string_append_char(message, str, " CROSS JOIN ");
2214                 }
2215                 else
2216                 {
2217                         delay_string_append_char(message, str, " JOIN ");
2218                         inner = true;
2219                 }
2220
2221         }
2222         else if (node->jointype == JOIN_LEFT)
2223         {
2224                 delay_string_append_char(message, str, " LEFT OUTER JOIN ");
2225                 left = true;
2226         }
2227         else if (node->jointype == JOIN_FULL)
2228         {
2229                 delay_string_append_char(message, str, " FULL OUTER JOIN ");
2230                 full = true;
2231         }
2232         else if (node->jointype == JOIN_RIGHT)
2233         {
2234                 delay_string_append_char(message, str, " RIGHT OUTER JOIN ");
2235                 right = true;
2236         }
2237
2238         _rewriteNode(BaseSelect, message, dblink, str, node->rarg);
2239
2240         r_state = message->table_state;
2241         message->fromClause = from;
2242         message->current_select = select_num;
2243
2244         if(message->r_code == SELECT_ANALYZE)
2245         {
2246                 if(cross && (IsA(node->rarg, RangeVar) || IsA(node->rarg,RangeSubselect)))
2247                         build_join_table(message,aliasname,JNORMAL);
2248
2249                 if(IsA(node->rarg, RangeVar) || IsA(node->rarg,RangeSubselect))
2250                 {
2251                         if(natural && inner)
2252                                 build_join_table(message,aliasname,JNATURAL_INNER);
2253                         else if(natural && left)
2254                                 build_join_table(message,aliasname,JNATURAL_LEFT);
2255                         else if(natural && right)
2256                                 build_join_table(message,aliasname,JNATURAL_RIGHT);
2257                         else if(natural && full)
2258                                 build_join_table(message,aliasname,JFULL);
2259                 }
2260         }
2261
2262         if (node->using != NIL && IsA(node->using, List))
2263         {
2264                 ListCell *lc;
2265                 char comma = 0;
2266                 int count = 0;
2267
2268                 using_length= list_length(node->using);
2269                 using_list = (char **) palloc(sizeof(char *) * using_length);
2270
2271                 if(message->r_code == SELECT_DEFAULT && message->rewritelock == -1
2272                                 && message->analyze[select_num]->state == 'S')
2273                 {
2274                         /* Rewrite Using Cluase to On Clause */
2275                         ConvertFromUsingToON(message, str, node, select_num);
2276                 } else {
2277                         delay_string_append_char(message, str, " USING(");
2278
2279                         foreach (lc, node->using)
2280                         {
2281                                 Value *value;
2282
2283                                 if (comma == 0)
2284                                         comma = 1;
2285                                 else
2286                                         delay_string_append_char(message, str, ",");
2287
2288                                 value = lfirst(lc);
2289                                 delay_string_append_char(message, str, value->val.str);
2290                                 using_list[count] = value->val.str;
2291                                 count++;
2292                         }
2293
2294                         message->analyze[select_num]->join->using_length = using_length;
2295                         message->analyze[select_num]->join->using_list = using_list;
2296
2297                         delay_string_append_char(message, str, ")");
2298                 }
2299         }
2300
2301         if(message->r_code == SELECT_ANALYZE)
2302         {
2303                 if(IsA(node->rarg, RangeVar) || IsA(node->rarg,RangeSubselect))
2304                 {
2305                 if(!natural && inner){
2306                                 build_join_table(message,aliasname,JINNER);
2307                         }
2308                         else if(!natural && left)
2309                                 build_join_table(message,aliasname,JLEFT);
2310                         else if(!natural && right)
2311                                 build_join_table(message,aliasname,JRIGHT);
2312                         else if(!natural && full)
2313                                 build_join_table(message,aliasname,JFULL);
2314                 }
2315                 message->analyze[select_num]->state = message->analyze[select_num]->join->state;
2316         }
2317         
2318         if (node->quals)
2319         {
2320                 int on_select = message->analyze_num - 1;
2321
2322                 delay_string_append_char(message, str, " ON ");
2323                 _rewriteNode(BaseSelect, message, dblink, str, node->quals);
2324
2325                 /* This condition means that the sub select is in ON CLAUSE*/
2326                 if(on_select < message->analyze_num -1)
2327                 {
2328                         int count = message->analyze_num - 1 - on_select;
2329                         char joinstate = message->analyze[select_num]->state;
2330
2331                         if(joinstate == 'S')
2332                                 return;
2333                         else 
2334                         {
2335                                 int i;
2336                                 for(i= on_select + 1; i < count + on_select + 1;i++)
2337                                 {
2338                                         char onstate = message->analyze[i]->state;
2339                                         if (onstate == 'S' || onstate == 'P')
2340                                         {
2341                                                 message->analyze[select_num]->state = 'S';
2342                                                 pool_debug("_rewriteJoinExpr: Change Join state from %c to %c",joinstate,
2343                                                                                                 message->analyze[select_num]->state);
2344                                                                                                 
2345                                                 return;
2346                                         }
2347                                 } 
2348                         }
2349                 }
2350         }
2351 }
2352
2353 static void
2354 _rewriteFromExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FromExpr *node)
2355 {
2356 }
2357
2358 /*****************************************************************************
2359  *
2360  *      Stuff from parsenodes.h.
2361  *
2362  *****************************************************************************/
2363
2364 static void
2365 _rewriteCreateStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateStmt *node)
2366 {
2367         delay_string_append_char(message, str, "CREATE ");
2368         if (node->relation->istemp)
2369                 delay_string_append_char(message, str, "TEMP ");
2370         delay_string_append_char(message, str, "TABLE ");
2371         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
2372         delay_string_append_char(message, str, " (");
2373         _rewriteNode(BaseSelect, message, dblink, str, node->tableElts);
2374         delay_string_append_char(message, str, ") ");
2375
2376         if (node->inhRelations != NIL)
2377         {
2378                 delay_string_append_char(message, str, "INHERITS (");
2379                 _rewriteNode(BaseSelect, message, dblink, str, node->inhRelations);
2380                 delay_string_append_char(message, str, ")");
2381         }
2382
2383         if (node->options)
2384                 _rewriteWithDefinition(BaseSelect, message, dblink, str, node->options);
2385
2386         switch (node->oncommit)
2387         {
2388                 case ONCOMMIT_DROP:
2389                         delay_string_append_char(message, str, " ON COMMIT DROP");
2390                         break;
2391
2392                 case ONCOMMIT_DELETE_ROWS:
2393                         delay_string_append_char(message, str, " ON COMMIT DELETE ROWS");
2394
2395                 case ONCOMMIT_PRESERVE_ROWS:
2396                         delay_string_append_char(message, str, " ON COMMIT PRESERVE ROWS");
2397                         break;
2398
2399                 default:
2400       break;
2401         }
2402
2403         if (node->tablespacename)
2404         {
2405                 delay_string_append_char(message, str, " TABLESPACE \"");
2406                 delay_string_append_char(message, str, node->tablespacename);
2407                 delay_string_append_char(message, str, "\"");
2408         }
2409 }
2410
2411 static void
2412 _rewriteIndexStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, IndexStmt *node)
2413 {
2414         delay_string_append_char(message, str, "CREATE ");
2415
2416         if (node->unique == TRUE)
2417                 delay_string_append_char(message, str, "UNIQUE ");
2418
2419    if (node->concurrent == true)
2420      delay_string_append_char(message, str, "INDEX CONCURRENTLY \"");
2421    else
2422      delay_string_append_char(message, str, "INDEX \"");
2423         delay_string_append_char(message, str, node->idxname);
2424         delay_string_append_char(message, str, "\" ON ");
2425         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
2426
2427         if (strcmp(node->accessMethod, DEFAULT_INDEX_TYPE))
2428         {
2429                 delay_string_append_char(message, str, " USING ");
2430                 delay_string_append_char(message, str, node->accessMethod);
2431         }
2432
2433         delay_string_append_char(message, str, "(");
2434         _rewriteNode(BaseSelect, message, dblink, str, node->indexParams);
2435         delay_string_append_char(message, str, ")");
2436
2437         if (node->tableSpace)
2438         {
2439                 delay_string_append_char(message, str, " TABLESPACE \"");
2440                 delay_string_append_char(message, str, node->tableSpace);
2441                 delay_string_append_char(message, str, "\"");
2442         }
2443
2444         if (node->whereClause)
2445         {
2446                 delay_string_append_char(message, str, " WHERE ");
2447                 _rewriteNode(BaseSelect, message, dblink, str, node->whereClause);
2448         }
2449 }
2450
2451 static void
2452 _rewriteNotifyStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, NotifyStmt *node)
2453 {
2454         delay_string_append_char(message, str, "NOTIFY ");
2455         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
2456 }
2457
2458 static void
2459 _rewriteDeclareCursorStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DeclareCursorStmt *node)
2460 {
2461         delay_string_append_char(message, str, "DECLARE \"");
2462         delay_string_append_char(message, str, node->portalname);
2463         delay_string_append_char(message, str, "\" ");
2464
2465         if (node->options & CURSOR_OPT_SCROLL)
2466                 delay_string_append_char(message, str, "SCROLL ");
2467         if (node->options & CURSOR_OPT_BINARY)
2468                 delay_string_append_char(message, str, "BINARY ");
2469         if (node->options & CURSOR_OPT_INSENSITIVE)
2470                 delay_string_append_char(message, str, "INSENSITIVE ");
2471
2472         delay_string_append_char(message, str, "CURSOR ");
2473
2474         if (node->options & CURSOR_OPT_HOLD)
2475                 delay_string_append_char(message, str, "WITH HOLD ");
2476
2477         delay_string_append_char(message, str, "FOR");
2478         _rewriteNode(BaseSelect, message, dblink, str, node->query);
2479 }
2480
2481 static void
2482 initSelectStmt(RewriteQuery *message,SelectStmt *node)
2483 {
2484         int count;
2485         int last;
2486         int i;
2487         AnalyzeSelect *analyze;
2488
2489         if(message->r_code != SELECT_ANALYZE && message->r_code != SELECT_DEFAULT)
2490                 return;
2491
2492         count = message->analyze_num++;
2493         last = message->current_select;
2494         message->current_select = count;
2495
2496         if(message->r_code == SELECT_ANALYZE)
2497         {
2498                 if(count == 0)
2499                 {
2500                         message->analyze = (AnalyzeSelect **) palloc(sizeof(AnalyzeSelect *));
2501                         message->analyze[count]=(AnalyzeSelect *) palloc(sizeof(AnalyzeSelect));
2502                         message->part = SELECT_START;
2503
2504                         analyze = message->analyze[count];
2505                         analyze->now_select = 0;
2506                         analyze->last_select = -1;
2507                         analyze->part = SELECT_START;
2508                         analyze->call_part = SELECT_START;
2509                 }
2510                 else
2511                 {
2512                         message->analyze = (AnalyzeSelect **) repalloc(message->analyze,sizeof(AnalyzeSelect *) * (count+1));
2513                         message->analyze[count]=(AnalyzeSelect *) palloc(sizeof(AnalyzeSelect));
2514                         analyze = message->analyze[count];
2515                         analyze->now_select = count;
2516                         analyze->last_select = last;
2517                         analyze->part = message->part;
2518                         analyze->call_part = message->analyze[last]->part;
2519                 }
2520
2521                 analyze->range =NULL;
2522                 analyze->rangeinfo_num =-1;
2523                 analyze->virtual = NULL;
2524                 analyze->join = NULL;
2525                 analyze->state = (char) 0;
2526                 analyze->aggregate = false;
2527                 analyze->aggexpr = NULL;
2528                 analyze->table_name = NULL;
2529                 analyze->select_range = false;
2530                 analyze->rarg_count = -1;
2531                 analyze->larg_count = -1;
2532                 analyze->ret_count = 0;
2533                 analyze->retlock = false;
2534
2535                 for(i = 0; i< 8; i++)
2536                         analyze->partstate[i] = (char)0;
2537
2538                 if(node->larg && node->rarg)
2539                         analyze->select_union = true;
2540                 else
2541                         analyze->select_union = false;
2542
2543                 pool_debug("initSelectStmt: ANALYZE now(%d)",message->current_select);
2544
2545                 /* set default table_state */
2546                 /* S means that tuples was create by systemdb */
2547                 /* L means that tuples was create by one node */
2548                 /* P means that tuples was create by parallel node */
2549                 message->table_state = 'S';
2550         }
2551 }
2552
2553 static void writeRangeHeader(RewriteQuery *message,ConInfoTodblink *dblink, String *str,DistDefInfo *info, RepliDefInfo *info2,char *alias)
2554 {
2555         char port[8];
2556         char *schema = NULL;
2557         char *table = NULL;
2558
2559
2560         pool_debug("writeRangeHeader select_no=%d",message->current_select);
2561
2562         sprintf(port,"%d",dblink->port);
2563
2564         delay_string_append_char(message, str, "dblink(");
2565         delay_string_append_char(message, str, "'");
2566         delay_string_append_char(message, str, "host=");
2567         delay_string_append_char(message, str, dblink->hostaddr);
2568         delay_string_append_char(message, str, " dbname=");
2569         delay_string_append_char(message, str, dblink->dbname);
2570         delay_string_append_char(message, str, " port=");
2571         delay_string_append_char(message, str, port);
2572         delay_string_append_char(message, str, " user=");
2573         delay_string_append_char(message, str, dblink->user);
2574
2575         if(strlen(dblink->password))
2576         {
2577                 delay_string_append_char(message, str, " password=");
2578                 delay_string_append_char(message, str, dblink->password);
2579         }
2580
2581         delay_string_append_char(message, str, "'");
2582         delay_string_append_char(message, str, ",");
2583         delay_string_append_char(message, str, "'");
2584
2585         if(info && !info2)
2586         {
2587                 delay_string_append_char(message, str, "SELECT pool_parallel(\"");
2588                 schema = info->schema_name;
2589                 if(alias)
2590                         table = alias;
2591                 else
2592                         table = info->table_name;
2593         }
2594         else if (!info && info2)
2595         {
2596                 delay_string_append_char(message, str, "SELECT pool_loadbalance(\"");
2597                 schema = info2->schema_name;
2598                 if(alias)
2599                         table = alias;
2600                 else
2601                         table = info2->table_name;
2602         }
2603
2604         {
2605                 VirtualTable *virtual = NULL;
2606                 int no = message->current_select;
2607                 int v_colnum;
2608                 int i;
2609                 int first = 0;
2610
2611                 AnalyzeSelect *analyze = message->analyze[no];
2612                 virtual = analyze->virtual;
2613                 v_colnum = virtual->col_num;
2614
2615                 delay_string_append_char(message, str, "SELECT ");
2616
2617                 for(i = 0; i < v_colnum; i++)
2618                 {
2619                         if(!strcmp(virtual->table_list[i],table) && virtual->valid[i] != -1)
2620                         {
2621
2622                                 if(first == 0)
2623                                 {
2624                                         delay_string_append_char(message, str, virtual->table_list[i]);
2625                                         delay_string_append_char(message, str, ".");
2626                                         delay_string_append_char(message, str, virtual->col_list[i]);
2627                                         first = 1;
2628                                 }
2629                                 else
2630                                 {
2631                                         delay_string_append_char(message, str, ", ");
2632                                         delay_string_append_char(message, str, virtual->table_list[i]);
2633                                         delay_string_append_char(message, str, ".");
2634                                         delay_string_append_char(message, str, virtual->col_list[i]);
2635                                 }
2636                         }
2637                 }
2638
2639                 if(first == 0)
2640                         delay_string_append_char(message, str, " * ");
2641
2642                 delay_string_append_char(message, str, " FROM ");
2643         }
2644 }
2645
2646 static void writeRangeFooter(RewriteQuery *message,ConInfoTodblink *dblink, String *str,DistDefInfo *info, RepliDefInfo *info2,char *alias)
2647 {
2648         int i,num;
2649         char *schema = NULL;
2650         char *table = NULL;
2651
2652         delay_string_append_char(message, str, "\"");
2653         delay_string_append_char(message, str, ")");
2654         delay_string_append_char(message, str, "'");
2655         delay_string_append_char(message, str, ",false)");
2656
2657         delay_string_append_char(message, str," AS ");
2658
2659         if(alias)
2660                 table = alias;
2661         else
2662         {
2663                 if(info && !info2)
2664                 {
2665                         schema = info->schema_name;
2666                         table = info->table_name;
2667                 }
2668                 else if (!info && info2)
2669                 {
2670                         schema = info2->schema_name;
2671                         table = info2->table_name;
2672                 }
2673         }
2674
2675         /* send one node */
2676         if(!table)
2677         {
2678                 message->r_code = SELECT_RELATION_ERROR;
2679         }
2680
2681         delay_string_append_char(message, str, table);
2682         delay_string_append_char(message, str, "(");
2683
2684         {
2685                 VirtualTable *virtual = NULL;
2686                 int first = 0;
2687                 int no = message->current_select;
2688                 AnalyzeSelect *analyze = message->analyze[no];
2689                 virtual = analyze->virtual;
2690                 num = virtual->col_num;
2691
2692                 for(i = 0; i < num; i++)
2693                 {
2694                         char buf[16];
2695                         if(!strcmp(virtual->table_list[i],table) && virtual->valid[i] != -1)
2696                         {
2697
2698                                 if(first == 0)
2699                                         first = 1;
2700                                 else
2701                                         delay_string_append_char(message, str, ",");
2702
2703                                 snprintf(buf, 16, "%d", analyze->virtual->column_no[i]);
2704                                 delay_string_append_char(message, str,"\"pool_c$");
2705                                 delay_string_append_char(message, str,buf);
2706                                 delay_string_append_char(message, str, "\"");
2707                                 delay_string_append_char(message, str, " ");
2708                                 delay_string_append_char(message, str,virtual->type_list[i]);
2709                         }
2710                 }
2711
2712                 if(first == 0)
2713                 {
2714                         for(i = 0; i < num; i++)
2715                         {
2716                                 char buf[16];
2717                                 if(!strcmp(virtual->table_list[i],table))
2718                                 {
2719                                         if(first == 0)
2720                                                 first = 1;
2721                                         else
2722                                                 delay_string_append_char(message, str, ",");
2723
2724                                         snprintf(buf, 16, "%d", analyze->virtual->column_no[i]);
2725                                         delay_string_append_char(message, str,"\"pool_c$");
2726                                         delay_string_append_char(message, str,buf);
2727                                         delay_string_append_char(message, str,"\"");
2728                                         delay_string_append_char(message, str, " ");
2729                                         delay_string_append_char(message, str,virtual->type_list[i]);
2730                                 }
2731                         }
2732                 }
2733                 delay_string_append_char(message, str, ")");
2734         }
2735 }
2736
2737 static void writeSelectAggHeader(RewriteQuery *message,ConInfoTodblink *dblink, String *str,int state)
2738 {
2739         char port[8];
2740         int count = message->current_select;
2741         AnalyzeSelect  *analyze;
2742         Aggexpr *agg;
2743         int i;
2744         int ret_count = 0;
2745
2746         analyze = message->analyze[count];
2747         agg = analyze->aggexpr;
2748
2749         ret_count = agg->t_num + agg->c_num + agg->h_num;
2750
2751         sprintf(port,"%d",dblink->port);
2752         pool_debug("writeSelectAggHeader select_no=%d state=%d",message->current_select,state);
2753
2754         delay_string_append_char(message, str, "dblink(");
2755         delay_string_append_char(message, str, "'");
2756         delay_string_append_char(message, str, "host=");
2757         delay_string_append_char(message, str, dblink->hostaddr);
2758         delay_string_append_char(message, str, " dbname=");
2759         delay_string_append_char(message, str, dblink->dbname);
2760         delay_string_append_char(message, str, " port=");
2761         delay_string_append_char(message, str, port);
2762         delay_string_append_char(message, str, " user=");
2763         delay_string_append_char(message, str, dblink->user);
2764
2765         if(strlen(dblink->password))
2766         {
2767                 delay_string_append_char(message, str, " password=");
2768                 delay_string_append_char(message, str, dblink->password);
2769         }
2770         delay_string_append_char(message, str, "'");
2771         delay_string_append_char(message, str, ",");
2772         delay_string_append_char(message, str, "'");
2773         delay_string_append_char(message, str, "SELECT pool_parallel(\"");
2774         delay_string_append_char(message, str, "SELECT ");
2775
2776         message->rewritelock = count;
2777
2778         for(i = 0; i< agg->t_num; i++)
2779         {
2780                 char *funcname = NULL;
2781                 funcname = strVal(lfirst(list_head(agg->tfunc_p[i]->funcname)));
2782                 if(strcmp(funcname,"avg"))
2783                 {
2784                         _rewriteFuncCall(NULL,message,NULL,str,agg->tfunc_p[i]);
2785                 }
2786                 else
2787                 {
2788                         AvgFuncCall(NULL,message,NULL,str,agg->tfunc_p[i]);
2789                 }
2790                 ret_count--;
2791                 if(ret_count != 0)
2792                         delay_string_append_char(message, str, ",");
2793         }
2794
2795         for(i = 0; i< agg->c_num; i++)
2796         {
2797                 _rewriteColumnRef(NULL,message,NULL,str,agg->col_p[i]);
2798                 ret_count--;
2799                 if(ret_count != 0)
2800                         delay_string_append_char(message, str, ",");
2801         }
2802
2803         for(i = 0; i< agg->h_num; i++)
2804         {
2805                 char *funcname = NULL;
2806                 funcname = strVal(lfirst(list_head(agg->hfunc_p[i]->funcname)));
2807                 if(strcmp(funcname,"avg"))
2808                 {
2809                         _rewriteFuncCall(NULL,message,NULL,str,agg->hfunc_p[i]);
2810                 }
2811                 else
2812                 {
2813                         AvgFuncCall(NULL,message,NULL,str,agg->hfunc_p[i]);
2814                 }
2815                 ret_count--;
2816                 if(ret_count != 0)
2817                         delay_string_append_char(message, str, ",");
2818         }
2819         delay_string_append_char(message, str, " FROM ");
2820 }
2821
2822 static void writeSelectHeader(RewriteQuery *message,ConInfoTodblink *dblink, String *str,int parallel,int state)
2823 {
2824         char port[8];
2825
2826         sprintf(port,"%d",dblink->port);
2827         pool_debug("writeSelectHeader select_no=%d state=%d",message->current_select,state);
2828
2829         if(state == SELECT_START)
2830         {
2831                 delay_string_append_char(message, str, "SELECT * FROM ");
2832         }
2833
2834         delay_string_append_char(message, str, "dblink(");
2835         delay_string_append_char(message, str, "'");
2836         delay_string_append_char(message, str, "host=");
2837         delay_string_append_char(message, str, dblink->hostaddr);
2838         delay_string_append_char(message, str, " dbname=");
2839         delay_string_append_char(message, str, dblink->dbname);
2840         delay_string_append_char(message, str, " port=");
2841         delay_string_append_char(message, str, port);
2842         delay_string_append_char(message, str, " user=");
2843         delay_string_append_char(message, str, dblink->user);
2844
2845         if(strlen(dblink->password))
2846         {
2847                 delay_string_append_char(message, str, " password=");
2848                 delay_string_append_char(message, str, dblink->password);
2849         }
2850         delay_string_append_char(message, str, "'");
2851         delay_string_append_char(message, str, ",");
2852         delay_string_append_char(message, str, "'");
2853         if(parallel)
2854                 delay_string_append_char(message, str, "SELECT pool_parallel(\"");
2855         else
2856                 delay_string_append_char(message, str, "SELECT pool_loadbalance(\"");
2857
2858         if(state == SELECT_FROMCLAUSE)
2859         {
2860                 int no = message->current_select;
2861                 int v_colnum;
2862                 int i;
2863                 int first = 0;
2864
2865                 AnalyzeSelect *analyze = message->analyze[no];
2866
2867                 v_colnum = analyze->virtual->col_num;
2868
2869                 delay_string_append_char(message, str, "SELECT ");
2870
2871                 for(i = 0; i < v_colnum; i++)
2872                 {
2873                         if(analyze->virtual->valid[i] != -1)
2874                         {
2875                                 char *col_name = analyze->virtual->col_list[i];
2876
2877                                 if(first == 0)
2878                                 {
2879                                         //delay_string_append_char(message, str, analyze->virtual->table_list[i]);
2880                                         //delay_string_append_char(message, str, "ooo.");
2881                                         if(strcmp(col_name,"\"?column?\""))
2882                                                 delay_string_append_char(message, str, col_name);
2883                                         else
2884                                         {
2885                                                 delay_string_append_char(message, str, "\"");
2886                                                 delay_string_append_char(message, str, col_name);
2887                                                 delay_string_append_char(message, str, "\"");
2888                                         }
2889                                         first = 1;
2890                                 }
2891                                 else
2892                                 {
2893                                         delay_string_append_char(message, str, ", ");
2894                                         delay_string_append_char(message, str, analyze->virtual->table_list[i]);
2895                                         delay_string_append_char(message, str, ".");
2896                                         if(strcmp(col_name,"\"?column?\""))
2897                                                 delay_string_append_char(message, str, col_name);
2898                                         else
2899                                         {
2900                                                 delay_string_append_char(message, str, "\"");
2901                                                 delay_string_append_char(message, str, col_name);
2902                                                 delay_string_append_char(message, str, "\"");
2903                                         }
2904                                 }
2905                         }
2906                 }
2907
2908                 if(first == 0)
2909                         delay_string_append_char(message, str, " * ");
2910
2911                 delay_string_append_char(message, str, " FROM ");
2912         }
2913 }
2914
2915 static char *estimateFuncTypes(AnalyzeSelect *analyze,FuncCall *func)
2916 {
2917         char *funcname = NULL;
2918         void *obj;
2919         char *type;
2920         obj = lfirst(list_head(func->args));
2921
2922         funcname = strVal(lfirst(list_head(func->funcname)));
2923
2924         if(!strcmp(funcname,"max") || !strcmp(funcname,"min"))
2925         {
2926                 if (obj && (IsA(obj, ColumnRef)))
2927                 {
2928                         char *table_name = NULL;
2929                         char *column_name = NULL;
2930                         VirtualTable  *virtual = analyze->virtual;
2931
2932                         column_name = GetNameFromColumnRef((ColumnRef *) obj,true);
2933                         table_name = GetNameFromColumnRef((ColumnRef *) obj ,false);
2934                         type = search_type_from_virtual(virtual,table_name,column_name);
2935                         return type;
2936                 }
2937                 else if( obj && (IsA(obj,TypeCast)))
2938                 {
2939                         TypeCast *typecast = (TypeCast *) obj;
2940                         TypeName *typename = (TypeName *)typecast->typename;
2941                         type = strVal(lfirst(list_head(typename->names)));
2942                         return type;
2943                 }
2944                 else
2945                 {
2946                 char *numeric = "numeric";
2947                         type = (char *) palloc(sizeof(char) * strlen(numeric) +1);
2948                         strcpy(type,numeric);
2949                         return type;
2950                 }
2951         }
2952         else if(!strcmp(funcname,"sum"))
2953         {
2954           char *numeric = "numeric";
2955                 type = (char *) palloc(sizeof(char) * strlen(numeric) +1);
2956                 strcpy(type,numeric);
2957                 return type;
2958         }
2959
2960         return "numeric";
2961 }
2962
2963 static void writeSelectAggFooter(RewriteQuery *message,String *str,AnalyzeSelect *analyze)
2964 {
2965         int count = message->current_select;
2966         Aggexpr *agg;
2967         int i;
2968         int ret_count = 0;
2969         int group_count = 0;
2970
2971         analyze = message->analyze[count];
2972         agg = analyze->aggexpr;
2973
2974         ret_count = agg->t_num + agg->c_num + agg->h_num;
2975
2976         group_count = agg->c_num;
2977
2978         if(group_count != 0)
2979         {
2980                 delay_string_append_char(message, str, " GROUP BY ");
2981
2982                 for(i = 0; i< agg->c_num; i++)
2983                 {
2984                         _rewriteColumnRef(NULL,message,NULL,str,agg->col_p[i]);
2985                         group_count--;
2986                         if(group_count != 0)
2987                                 delay_string_append_char(message, str, ",");
2988                 }
2989         }
2990
2991         delay_string_append_char(message, str, "\"");
2992         delay_string_append_char(message, str, ")");
2993         delay_string_append_char(message, str, "'");
2994         delay_string_append_char(message, str, ",false)");
2995
2996         delay_string_append_char(message, str," AS ");
2997         delay_string_append_char(message, str, analyze->table_name);
2998
2999         /* symbol of aggregate opt */
3000         delay_string_append_char(message, str,"g");
3001         delay_string_append_char(message, str, " (");
3002
3003         message->rewritelock = -1;
3004
3005         for(i = 0; i < ret_count; i++)
3006         {
3007                 char buf[16];
3008                 snprintf(buf, 16, "%d", i);
3009                 delay_string_append_char(message, str, "pool_g$");
3010                 delay_string_append_char(message, str, buf);
3011                 delay_string_append_char(message, str, " ");
3012
3013                 if(i < agg->t_num)
3014                 {
3015                         char *funcname = NULL;
3016                         funcname = strVal(lfirst(list_head(agg->tfunc_p[i]->funcname)));
3017                         if(!strcmp(funcname,"count"))
3018                                 delay_string_append_char(message, str, "bigint ");
3019                         else if(!strcmp(funcname,"avg"))
3020                         {
3021                                 delay_string_append_char(message, str, "numeric ");
3022                                 delay_string_append_char(message, str, ",");
3023                                 delay_string_append_char(message, str, "pool_g$");
3024                                 delay_string_append_char(message, str, buf);
3025                                 delay_string_append_char(message, str, "c");
3026                                 delay_string_append_char(message, str, " ");
3027                                 delay_string_append_char(message, str, "bigint ");
3028                         }
3029                         else
3030                         {
3031                                 char *type = estimateFuncTypes(analyze,agg->tfunc_p[i]);
3032                                 delay_string_append_char(message, str, type);
3033                         }
3034                 }
3035                 else if(i >= agg->t_num && i < agg->t_num + agg->c_num)
3036                 {
3037                         char *table_name = NULL;
3038                         char *column_name = NULL;
3039                         char *type = NULL;
3040                         VirtualTable  *virtual = analyze->virtual;
3041
3042                         column_name = GetNameFromColumnRef(agg->col_p[i - agg->t_num],true);
3043                         table_name = GetNameFromColumnRef(agg->col_p[i - agg->t_num],false);
3044                         type = search_type_from_virtual(virtual,table_name,column_name);
3045                         delay_string_append_char(message, str, type);
3046                 }
3047                 else if(i >= agg->t_num + agg->c_num)
3048                 {
3049                         char *funcname = NULL;
3050                         int arg = i - agg->t_num - agg->c_num;
3051                         funcname = strVal(lfirst(list_head(agg->hfunc_p[arg]->funcname)));
3052                         if(!strcmp(funcname,"count"))
3053                                 delay_string_append_char(message, str, "bigint ");
3054                         else if(!strcmp(funcname,"avg"))
3055                         {
3056                                 delay_string_append_char(message, str, "numeric ");
3057                                 delay_string_append_char(message, str, ",");
3058                                 delay_string_append_char(message, str, "pool_g$");
3059                                 delay_string_append_char(message, str, buf);
3060                                 delay_string_append_char(message, str, "c");
3061                                 delay_string_append_char(message, str, " ");
3062                                 delay_string_append_char(message, str, "bigint ");
3063                         }
3064                         else
3065                         {
3066                                 char *type = estimateFuncTypes(analyze,agg->hfunc_p[arg]);
3067                                 delay_string_append_char(message, str, type);
3068                         }
3069                 }
3070
3071                 if( i + 1 != ret_count)
3072                         delay_string_append_char(message, str, ",");
3073         }
3074         delay_string_append_char(message, str, ") ");
3075 }
3076
3077 static void writeSelectFooter(RewriteQuery *message,String *str,AnalyzeSelect *analyze,int state)
3078 {
3079         int i,num;
3080
3081         delay_string_append_char(message, str, "\"");
3082         delay_string_append_char(message, str, ")");
3083         delay_string_append_char(message, str, "'");
3084         delay_string_append_char(message, str, ",false)");
3085
3086         delay_string_append_char(message, str," AS ");
3087         delay_string_append_char(message, str, analyze->table_name);
3088         delay_string_append_char(message, str, "(");
3089   pool_debug("writeSelectFooter %s",analyze->table_name);
3090
3091         if(state != SELECT_FROMCLAUSE)
3092         {
3093                 num = analyze->select_ret->col_num;
3094                 for(i = 0; i < num; i++)
3095                 {
3096                         delay_string_append_char(message, str, analyze->select_ret->col_list[i]);
3097                         delay_string_append_char(message, str, " ");
3098                         delay_string_append_char(message, str, analyze->select_ret->type_list[i]);
3099                         if (i != num -1)
3100                                 delay_string_append_char(message, str, ",");
3101                 }
3102                 delay_string_append_char(message, str, ")");
3103         }
3104         else
3105         {
3106                 int first = 0;
3107                 num = analyze->virtual->col_num;
3108
3109                 for(i = 0; i < num; i++)
3110                 {
3111                         if(analyze->virtual->valid[i] != -1)
3112                         {
3113                                 char buf[16];
3114                                 if(first == 0)
3115                                 {
3116                                         snprintf(buf, 16, "%d", analyze->virtual->column_no[i]);
3117                                         delay_string_append_char(message, str, "\"pool_c$");
3118                                         delay_string_append_char(message, str, buf);
3119                                         delay_string_append_char(message, str, "\"");
3120                                         delay_string_append_char(message, str, " ");
3121                                         delay_string_append_char(message, str, analyze->virtual->type_list[i]);
3122                                         first = 1;
3123                                 } else {
3124                                         delay_string_append_char(message, str, ",");
3125                                         snprintf(buf, 16, "%d", analyze->virtual->column_no[i]);
3126                                         delay_string_append_char(message, str, "\"pool_c$");
3127                                         delay_string_append_char(message, str, buf);
3128                                         delay_string_append_char(message, str, "\"");
3129                                         delay_string_append_char(message, str, " ");
3130                                         delay_string_append_char(message, str, analyze->virtual->type_list[i]);
3131                                 }
3132                         }
3133                 }
3134
3135                 if(first == 0)
3136                 {
3137                         for(i = 0; i < num; i++)
3138                         {
3139                                 if(first == 0)
3140                                 {
3141                                         delay_string_append_char(message, str, analyze->virtual->col_list[i]);
3142                                         delay_string_append_char(message, str, " ");
3143                                         delay_string_append_char(message, str, analyze->virtual->type_list[i]);
3144                                         first = 1;
3145                                 } else {
3146                                         delay_string_append_char(message, str, ",");
3147                                         delay_string_append_char(message, str, analyze->virtual->col_list[i]);
3148                                         delay_string_append_char(message, str, " ");
3149                                         delay_string_append_char(message, str, analyze->virtual->type_list[i]);
3150                                 }
3151                         }
3152                 }
3153
3154                 delay_string_append_char(message, str, ")");
3155         }
3156 }
3157
3158 static void
3159 CopyFromLeftArg(RewriteQuery *message,int current_num)
3160 {
3161         AnalyzeSelect *l_analyze = message->analyze[current_num + 1];
3162         AnalyzeSelect *analyze = message->analyze[current_num];
3163         VirtualTable  *virtual = message->analyze[current_num]->virtual;
3164         int col_num;
3165         int i;
3166         char **col_list = NULL;
3167         char **type_list = NULL;
3168         char state;
3169         char *table_name;
3170
3171         table_name = l_analyze->table_name;
3172         col_list  = l_analyze->select_ret->col_list;
3173         type_list = l_analyze->select_ret->type_list;
3174         col_num   = l_analyze->select_ret->col_num;
3175
3176         state = l_analyze->state;
3177   append_virtual_table(message,virtual,col_list,type_list,col_num,table_name,state,current_num + 1);
3178
3179         analyze->select_ret = (SelectDefInfo *) palloc(sizeof(SelectDefInfo));
3180         analyze->select_ret->valid = false;
3181         analyze->select_ret->col_num = 0;
3182         for(i =0; i<col_num; i++)
3183         {
3184                 append_select_def_info(analyze->select_ret,col_list[i],type_list[i]);
3185         }
3186 }
3187
3188
3189 static void
3190 ChangeStateByCluase(RewriteQuery *message,void *obj,int before, int after)
3191 {
3192         AnalyzeSelect *analyze;
3193         int count = message->current_select;
3194
3195         if(message->r_code != SELECT_ANALYZE)
3196                 return;
3197
3198         analyze = message->analyze[count];
3199
3200         if (obj && analyze->partstate[before] == 'P')
3201                         analyze->partstate[after] = 'S';
3202         else
3203                         analyze->partstate[after] = analyze->partstate[before];
3204 }
3205
3206 static void
3207 ChangeStateRewriteFooter(RewriteQuery *message,String *str,int defore, int after)
3208 {
3209         AnalyzeSelect *analyze;
3210         int count = message->current_select;
3211         char state;
3212
3213         if(message->r_code != SELECT_DEFAULT)
3214                 return;
3215
3216         analyze = message->analyze[count];
3217
3218         if(analyze->state == 'S' && message->rewritelock == count
3219                 && message->ignore_rewrite == -1)
3220         {
3221                 state = analyze->partstate[defore];
3222
3223                 if(state == 'L' || state == 'P')
3224                 {
3225                         if(state != analyze->partstate[after])
3226                         {
3227                                 writeSelectFooter(message,str,analyze,SELECT_FROMCLAUSE);
3228                                 message->rewritelock = -1;
3229                         }
3230                 }
3231         }
3232 }
3233
3234 static bool
3235 CheckUnionFromClause(RewriteQuery *message)
3236 {
3237         int check;
3238         int count = message->current_select;
3239         AnalyzeSelect *analyze;
3240         analyze = message->analyze[count];
3241
3242         check = analyze->last_select;
3243         pool_debug("CheckUnion select=%d last_select=%d", count,check);
3244
3245         if(check == -1)
3246                 return false;
3247         else
3248         {
3249                 if(message->analyze[check]->select_union &&
3250                                 message->analyze[check]->call_part == SELECT_FROMCLAUSE)
3251                 {
3252                         pool_debug("CheckUnion true");
3253                         return true;
3254                 }
3255                 else
3256                         return false;
3257         }
3258 }
3259
3260 static void
3261 _rewriteSelectStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SelectStmt *node)
3262 {
3263         BaseSelect = (Node *) node;
3264         AnalyzeSelect *analyze;
3265         int count;
3266         int analyze_num = 0;
3267         int target_analyze = 0;
3268         int from_analyze = 0;
3269         bool lock = false;
3270         bool direct = false;
3271         bool aggrewrite = false;
3272
3273         count = message->analyze_num;
3274
3275   /* Allocate Memory Space and initialize some Flags*/
3276         initSelectStmt(message,node);
3277
3278         if(message->r_code == SELECT_DEFAULT)
3279         {
3280                 if(message->current_select == 0)
3281                         pool_debug("_rewriteSelectStmt:START QueryRewrite");
3282         }
3283
3284         analyze_num = message->analyze_num;
3285
3286         analyze = message->analyze[count];
3287         analyze->part = SELECT_START;
3288
3289         if(message->r_code == SELECT_DEFAULT && message->rewritelock == -1
3290                         && message->ignore_rewrite == -1)
3291         {
3292 #if 0
3293                 if(analyze->state == 'P')
3294                 {
3295                         if(analyze->call_part != SELECT_FROMCLAUSE || !CheckUnionFromClause(message))
3296                         {
3297                                 writeSelectHeader(message,dblink,str,PARALLEL,analyze->part);
3298                                 message->rewritelock = count;
3299                                 direct = true;
3300                         }
3301                         else
3302                                 lock =true;
3303                 }
3304 #endif
3305                 if(analyze->state == 'L')
3306                 {
3307                         if(analyze->call_part != SELECT_FROMCLAUSE && !CheckUnionFromClause(message))
3308                         {
3309                                 writeSelectHeader(message,dblink,str,LOADBALANCE,analyze->part);
3310                                 message->rewritelock = count;
3311                                 direct = true;
3312                         }
3313                         else
3314                                 lock =true;
3315                 }
3316         }
3317
3318         if (node->larg) /* SETOP */
3319         {
3320                 if(message->r_code == SELECT_ANALYZE)
3321                 {
3322                         char buf[16];
3323                         char *temp = "pool_t$";
3324                         analyze->virtual = (VirtualTable *) palloc(sizeof(VirtualTable));
3325                         snprintf(buf, 16, "%d", message->virtual_num);
3326                         message->virtual_num++;
3327                         analyze->table_name = (char *) palloc(sizeof(char) * (strlen(temp) + strlen(buf) + 1));
3328                         strcpy(analyze->table_name,temp);
3329                         strcat(analyze->table_name,buf);
3330                         analyze->virtual->col_num = 0;
3331                 }
3332
3333                 delay_string_append_char(message, str, "(");
3334                 message->part = SELECT_START;
3335                 _rewriteNode(BaseSelect, message, dblink, str, node->larg);
3336                 pool_debug("union larg select_no=%d(%d)",count,message->analyze_num);
3337
3338                 delay_string_append_char(message, str, ")");
3339                 KeepMessages(message,count,SELECT_START);
3340
3341                 /* COPY analyze of left arg */
3342                 if(message->r_code == SELECT_ANALYZE)
3343                 {
3344                         analyze->larg_count = count + 1;
3345                         analyze->rarg_count = message->analyze_num;
3346                         pool_debug("_rewriteSelectStmt: COUNT larg=%d, rarg=%d",analyze->larg_count, analyze->rarg_count);
3347                 }
3348
3349                 switch (node->op)
3350                 {
3351                         case SETOP_UNION:
3352                                 delay_string_append_char(message, str, " UNION ");
3353                                 break;
3354
3355                         case SETOP_INTERSECT:
3356                                 delay_string_append_char(message, str, " INTERSECT ");
3357                                 break;
3358
3359                         case SETOP_EXCEPT:
3360                                 delay_string_append_char(message, str, " EXCEPT ");
3361
3362                         default:
3363                                 break;
3364                 }
3365
3366                 if (node->all)
3367                         delay_string_append_char(message, str, "ALL ");
3368
3369                 if (node->rarg)
3370                 {
3371                         delay_string_append_char(message, str, "(");
3372                         message->part = SELECT_START;
3373                         _rewriteNode(BaseSelect, message, dblink, str, node->rarg);
3374                         delay_string_append_char(message, str, ")");
3375                         KeepMessages(message,count,SELECT_START);
3376
3377                         if(message->r_code == SELECT_ANALYZE)
3378                                 CopyFromLeftArg(message,count);
3379                 }
3380
3381                 if(message->r_code == SELECT_ANALYZE)
3382                 {
3383                         pool_debug("_rewriteSelectStmt: STATE larg=%c, rarg=%c",message->analyze[analyze->larg_count]->state,
3384                                                                                                                                                                                                                                                         message->analyze[analyze->rarg_count]->state);
3385
3386                 }
3387
3388                 if(message->r_code == SELECT_DEFAULT)
3389                 {
3390                         pool_debug("_rewriteSelectStmt: DEFAULT COUNT larg=%d, rarg=%d",analyze->larg_count, analyze->rarg_count);
3391                 }
3392
3393                 if(message->r_code == SELECT_ANALYZE)
3394                 {
3395                         int lcount = analyze->larg_count;
3396                         int rcount = analyze->rarg_count;
3397                         if(message->analyze[lcount]->state == 'L' &&
3398                                  message->analyze[rcount]->state == 'L')
3399                         {
3400                                 int j;
3401                                 for(j = 0; j < SELECT_SORTCLAUSE; j++)
3402                                 {
3403                                         analyze->partstate[j]='L';
3404                                 }
3405                         }
3406                         else
3407                         {
3408                                 int j;
3409                                 for(j = 0; j < SELECT_SORTCLAUSE; j++)
3410                                 {
3411                                         analyze->partstate[j]='S';
3412                                 }
3413                         }
3414                 }
3415         }
3416         else
3417         {
3418                 if (node->intoClause)
3419                 {
3420                         IntoClause *into = node->intoClause;
3421                         RangeVar *rel = (RangeVar *)into->rel;
3422
3423                         delay_string_append_char(message, str, "CREATE ");
3424                         if (rel->istemp == true)
3425                                 delay_string_append_char(message, str, "TEMP ");
3426                         delay_string_append_char(message, str, "TABLE ");
3427                         _rewriteNode(BaseSelect, message, dblink, str, into->rel);
3428                         KeepRewriteQueryReturnCode(message, SELECT_RELATION_ERROR);
3429
3430                         if (into->colNames)
3431                         {
3432                                 delay_string_append_char(message, str, " (");
3433                                 _rewriteNode(BaseSelect, message, dblink, str, into->colNames);
3434                                 delay_string_append_char(message, str, ") ");
3435                                 KeepRewriteQueryReturnCode(message, SELECT_RELATION_ERROR);
3436                         }
3437
3438                         if (into->options)
3439                                 _rewriteWithDefinition(BaseSelect, message, dblink, str, into->options);
3440
3441                         switch (into->onCommit)
3442                         {
3443                                 case ONCOMMIT_DROP:
3444                                         delay_string_append_char(message, str, " ON COMMIT DROP");
3445                                         break;
3446
3447                                 case ONCOMMIT_DELETE_ROWS:
3448                                         delay_string_append_char(message, str, " ON COMMIT DELETE ROWS");
3449                                         break;
3450
3451                                 case ONCOMMIT_PRESERVE_ROWS:
3452                                         delay_string_append_char(message, str, " ON COMMIT PRESERVE ROWS");
3453                                         break;
3454
3455                                 default:
3456                                         break;
3457                         }
3458                         delay_string_append_char(message, str, " AS");
3459                 }
3460
3461                 delay_string_append_char(message, str, " SELECT ");
3462
3463                 /*
3464      * Check from-clause before Checking target-list
3465      */
3466                 if(node->fromClause)
3467                 {
3468                         message->part = SELECT_FROMCLAUSE;
3469                         analyze->part = SELECT_FROMCLAUSE;
3470                         message->fromClause = true;
3471
3472                         if(message->r_code == SELECT_ANALYZE)
3473                         {
3474                                 char buf[16];
3475                                 char *temp = "pool_t$";
3476                                 analyze->virtual = (VirtualTable *) palloc(sizeof(VirtualTable));
3477                                 snprintf(buf, 16, "%d", message->virtual_num);
3478                                 message->virtual_num++;
3479                                 analyze->table_name = (char *) palloc(sizeof(char) * (strlen(temp) + strlen(buf) + 1));
3480                                 strcpy(analyze->table_name,temp);
3481                                 strcat(analyze->table_name,buf);
3482                                 analyze->virtual->col_num = 0;
3483                         }
3484
3485                         if(message->r_code == SELECT_DEFAULT && message->ignore_rewrite == -1)
3486                                 message->ignore_rewrite = count;
3487
3488       /* remember analyze_num */
3489                         from_analyze = message->analyze_num;
3490
3491                         _rewriteNode(BaseSelect, message, dblink, str, node->fromClause);
3492
3493                         if(message->r_code == SELECT_DEFAULT && message->ignore_rewrite == count)
3494                                 message->ignore_rewrite = -1;
3495
3496                         message->fromClause = false;
3497
3498                         if(message->r_code == SELECT_ANALYZE)
3499                         {
3500                                 message->table_state = analyze->state;
3501                                 analyze->partstate[SELECT_FROMCLAUSE] = analyze->state;
3502                         }
3503                 }
3504                 else
3505                 {
3506                         /* this is const or function call*/
3507                         message->part = SELECT_TARGETLIST;
3508                         if(message->r_code == SELECT_ANALYZE)
3509                                 build_range_info(message,NULL,NULL,NULL,NULL,message->current_select,-1);
3510                 }
3511
3512                 message->part = SELECT_OTHER;
3513                 analyze->part = SELECT_OTHER;
3514
3515                 if (message->r_code == SELECT_ANALYZE && node->groupClause)
3516                 {
3517                         analyze->aggregate = true;
3518                 }
3519
3520                 if (node->distinctClause)
3521                 {
3522                         if(message->r_code == SELECT_ANALYZE)
3523                                 analyze->partstate[SELECT_TARGETLIST] = 'S';
3524 #if 0
3525                         /* TODO
3526        * DISTINCT optimization
3527        */
3528                         if(message->r_code == SELECT_ANALYZE)
3529                                 analyze->aggregate = true;
3530 #endif
3531                         delay_string_append_char(message, str, "DISTINCT ");
3532                         if (lfirst(list_head(node->distinctClause)) != NIL)
3533                         {
3534                                 delay_string_append_char(message, str, "ON (");
3535                                 _rewriteNode(BaseSelect, message, dblink,str, node->distinctClause);
3536                                 KeepMessages(message,count,SELECT_OTHER);
3537                                 delay_string_append_char(message, str, ") ");
3538                         }
3539                 }
3540
3541                 message->part = SELECT_TARGETLIST;
3542                 analyze->part = SELECT_TARGETLIST;
3543
3544                 if(analyze->partstate[SELECT_FROMCLAUSE] == 'P' && analyze->aggregate)
3545                         analyze->partstate[SELECT_TARGETLIST] = 'S';
3546
3547                 /* TARGETLIST START */
3548                 _rewriteNode(BaseSelect, message, dblink, str, node->targetList);
3549
3550                 aggrewrite = CheckAggOpt(message);
3551
3552                 target_analyze = message->analyze_num;
3553
3554                 if(message->r_code == SELECT_ANALYZE)
3555                 {
3556                         if (analyze->aggregate && (analyze->partstate[SELECT_FROMCLAUSE] == 'P'
3557                                         || analyze->partstate[SELECT_TARGETLIST] == 'P'))
3558                                         analyze->partstate[SELECT_TARGETLIST] = 'S';
3559                         else if (!analyze->partstate[SELECT_TARGETLIST])
3560                                 analyze->partstate[SELECT_TARGETLIST] = analyze->partstate[SELECT_FROMCLAUSE];
3561                 }
3562
3563                 KeepMessages(message,count,SELECT_TARGETLIST);
3564
3565                 if (node->fromClause && message->r_code != SELECT_ANALYZE)
3566                 {
3567
3568                         message->analyze_num = from_analyze;
3569
3570                         message->part = SELECT_FROMCLAUSE;
3571                         analyze->part = SELECT_FROMCLAUSE;
3572                         delay_string_append_char(message, str, " FROM ");
3573
3574                         if(message->r_code == SELECT_DEFAULT &&
3575                                         (analyze->state == 'S' || lock)
3576                                         && message->rewritelock == -1 && message->ignore_rewrite ==-1)
3577                         {
3578                                 if(analyze->partstate[SELECT_FROMCLAUSE] == 'L')
3579                                 {
3580                                         writeSelectHeader(message,dblink,str,LOADBALANCE, message->part);
3581                                         message->rewritelock = count;
3582                                 }
3583                                 else if(analyze->partstate[SELECT_FROMCLAUSE] == 'P')
3584                                 {
3585                                         if(aggrewrite)
3586                                         {
3587                                                 writeSelectAggHeader(message,dblink,str, message->part);
3588                                         }
3589                                         else
3590                                         {
3591                                                 writeSelectHeader(message,dblink,str,PARALLEL, message->part);
3592                                         }
3593                                         message->rewritelock = count;
3594                                 }
3595                         }
3596
3597                         message->fromClause = true;
3598                         _rewriteNode(BaseSelect, message, dblink, str, node->fromClause);
3599                         message->fromClause = false;
3600                         KeepMessages(message,count,SELECT_FROMCLAUSE);
3601
3602                         if(message->r_code == SELECT_DEFAULT && analyze->state == 'S'
3603                                         && message->rewritelock == count && message->ignore_rewrite == -1)
3604                         {
3605                                 if(analyze->partstate[SELECT_FROMCLAUSE] == 'L')
3606                                 {
3607                                         if(analyze->partstate[SELECT_WHERECLAUSE] != 'L')
3608                                         {
3609                                                 if(node->whereClause)
3610                                                 {
3611                                                         int message_code = message->r_code;
3612                                                         delay_string_append_char(message, str, " WHERE ");
3613                                                         CheckWhereCaluse(node->whereClause, message,dblink,str,0);
3614                                                         KeepRewriteQueryReturnCode(message, message_code);
3615                                                 }
3616
3617                                                 writeSelectFooter(message,str,analyze,SELECT_FROMCLAUSE);
3618                                                 message->rewritelock = -1;
3619                                         }
3620                                 }
3621                                 else if(analyze->partstate[SELECT_FROMCLAUSE] == 'P')
3622                                 {
3623                                         if(analyze->partstate[SELECT_WHERECLAUSE] != 'P')
3624                                         {
3625                                                 if(node->whereClause)
3626                                                 {
3627                                                         int message_code = message->r_code;
3628                                                         delay_string_append_char(message, str, " WHERE ");
3629                                                         CheckWhereCaluse(node->whereClause, message,dblink,str,0);
3630                                                         KeepRewriteQueryReturnCode(message, message_code);
3631                                                 }
3632                                                 writeSelectFooter(message,str,analyze,SELECT_FROMCLAUSE);
3633                                                 message->rewritelock = -1;
3634                                         }
3635                                 }
3636                         }
3637                         message->analyze_num = target_analyze;
3638                 }
3639
3640                 /* WHERE CLAUSE */
3641
3642                 message->part = SELECT_OTHER;
3643                 if (node->whereClause)
3644                         BaseSelect = NULL;
3645
3646                 if (node->whereClause)
3647                 {
3648                         message->part = SELECT_WHERECLAUSE;
3649                         analyze->part = SELECT_WHERECLAUSE;
3650                         delay_string_append_char(message, str, " WHERE ");
3651                         _rewriteNode(BaseSelect, message, dblink, str, node->whereClause);
3652                         KeepMessages(message,count,SELECT_OTHER);
3653                 }
3654
3655                 if(!analyze->partstate[SELECT_WHERECLAUSE] && message->r_code == SELECT_ANALYZE)
3656                         analyze->partstate[SELECT_WHERECLAUSE] = analyze->partstate[SELECT_FROMCLAUSE];
3657
3658                 if(aggrewrite)
3659                                 writeSelectAggFooter(message,str,analyze);
3660                 else
3661                         ChangeStateRewriteFooter(message,str,SELECT_WHERECLAUSE, SELECT_GROUPBYCLAUSE);
3662
3663                 /* GROUPBY CLAUSE */
3664                 if (node->groupClause)
3665                 {
3666                         analyze->part = SELECT_GROUPBYCLAUSE;
3667                         delay_string_append_char(message, str, " GROUP BY ");
3668                         _rewriteNode(BaseSelect, message, dblink, str, node->groupClause);
3669                         KeepMessages(message,count,SELECT_OTHER);
3670                 }
3671
3672                 ChangeStateByCluase(message,node->groupClause,SELECT_WHERECLAUSE,SELECT_GROUPBYCLAUSE);
3673
3674                 /* HAVING CLAUSE */
3675                 if (node->havingClause)
3676                 {
3677                         analyze->part = SELECT_HAVINGCLAUSE;
3678                         delay_string_append_char(message, str, " HAVING ");
3679                         _rewriteNode(BaseSelect, message, dblink, str, node->havingClause);
3680                         KeepMessages(message,count,SELECT_OTHER);
3681
3682                 }
3683
3684                 if(message->r_code == SELECT_ANALYZE)
3685                         analyze->partstate[SELECT_HAVINGCLAUSE] = analyze->partstate[SELECT_GROUPBYCLAUSE];
3686         }
3687
3688         ChangeStateRewriteFooter(message,str,SELECT_HAVINGCLAUSE, SELECT_SORTCLAUSE);
3689
3690         if (node->sortClause)
3691         {
3692                 analyze->part = SELECT_SORTCLAUSE;
3693                 delay_string_append_char(message, str, " ORDER BY ");
3694                 _rewriteNode(BaseSelect, message, dblink, str, node->sortClause);
3695                 KeepMessages(message,count,SELECT_OTHER);
3696         }
3697
3698         ChangeStateByCluase(message,node->sortClause,SELECT_HAVINGCLAUSE,SELECT_SORTCLAUSE);
3699
3700
3701         ChangeStateRewriteFooter(message,str, SELECT_SORTCLAUSE, SELECT_OFFSETCLAUSE);
3702
3703         if (node->limitOffset)
3704         {
3705                 analyze->part = SELECT_OFFSETCLAUSE;
3706                 delay_string_append_char(message, str, " OFFSET ");
3707                 _rewriteNode(BaseSelect, message, dblink, str, node->limitOffset);
3708                 KeepMessages(message,count,SELECT_OTHER);
3709
3710         }
3711
3712         ChangeStateByCluase(message,node->limitOffset,SELECT_SORTCLAUSE,SELECT_OFFSETCLAUSE);
3713
3714         ChangeStateRewriteFooter(message,str,SELECT_OFFSETCLAUSE,SELECT_LIMITCLAUSE);
3715
3716         if (node->limitCount)
3717         {
3718                 analyze->part = SELECT_LIMITCLAUSE;
3719                 delay_string_append_char(message, str, " LIMIT ");
3720                 if (IsA(node->limitCount, A_Const) &&
3721                         ((A_Const *)node->limitCount)->val.type == T_Null)
3722                 {
3723                         delay_string_append_char(message, str, "ALL ");
3724                 }
3725                 else
3726                 {
3727                         _rewriteNode(BaseSelect, message, dblink, str, node->limitCount);
3728                         KeepMessages(message,count,SELECT_OTHER);
3729                 }
3730         }
3731
3732         ChangeStateByCluase(message,node->limitCount,SELECT_OFFSETCLAUSE,SELECT_LIMITCLAUSE);
3733
3734         if(message->r_code == SELECT_ANALYZE)
3735         {
3736                 int i;
3737                 analyze->state = analyze->partstate[SELECT_LIMITCLAUSE];
3738
3739                 for(i = 0; i< 8; i++)
3740                 {
3741                         char s = analyze->partstate[i];
3742                         if(s == 'S')
3743                         {
3744                                 analyze->state = s;
3745                                 break;
3746                         }
3747                 }
3748         }
3749
3750         _rewriteNode(BaseSelect, message, dblink, str, node->lockingClause);
3751         KeepMessages(message,count,SELECT_OTHER);
3752
3753         if(message->r_code == SELECT_ANALYZE)
3754         {
3755                 if(node->targetList)
3756                         AnalyzeReturnRecord(BaseSelect,message,dblink,str,node->targetList);
3757
3758                 pool_debug("_rewriteSelectStmt select_no=%d state=%s",message->current_select,analyze->partstate);
3759
3760                 if(strstr(analyze->partstate,"E"))
3761                         message->is_loadbalance = true;
3762
3763         /* change state */
3764                 if(count != 0)
3765                 {
3766                         AnalyzeSelect *last = message->analyze[analyze->last_select];
3767                         if(last->part == SELECT_WHERECLAUSE)
3768                         {
3769                                 char fromstate = last->partstate[SELECT_FROMCLAUSE];
3770                                 char wherestate = (char) 0;
3771
3772                                 if(last->partstate[SELECT_WHERECLAUSE])
3773                                         wherestate = last->partstate[SELECT_WHERECLAUSE];
3774
3775                                 if(fromstate == 'P' && analyze->state == 'L')
3776                                 {
3777                                         if(wherestate && wherestate == 'P')
3778                                                 last->partstate[SELECT_WHERECLAUSE] = 'P';
3779                                 }
3780                                 else if(fromstate == 'L' && analyze->state == 'L')
3781                                 {
3782                                         last->partstate[SELECT_WHERECLAUSE] = 'L';
3783                                 }
3784                                 else
3785                                         last->partstate[SELECT_WHERECLAUSE] = 'S';
3786                         }
3787
3788                         if(last->part == SELECT_TARGETLIST)
3789                         {
3790                                 char fromstate = last->partstate[SELECT_FROMCLAUSE];
3791                                 char targetstate = (char) 0;
3792
3793                                 if(last->partstate[SELECT_TARGETLIST])
3794                                         targetstate = last->partstate[SELECT_TARGETLIST];
3795
3796                                 if(fromstate == 'P' && analyze->state == 'L')
3797                                 {
3798                                         last->partstate[SELECT_TARGETLIST] = 'P';
3799                                 }
3800                                 else if(fromstate == 'L' && analyze->state == 'L')
3801                                 {
3802                                         last->partstate[SELECT_TARGETLIST] = 'L';
3803                                 }
3804                                 else
3805                                         last->partstate[SELECT_TARGETLIST] = 'S';
3806                         }
3807                 }
3808         }
3809
3810         if(message->r_code == SELECT_DEFAULT && message->rewritelock == count
3811                 && message->ignore_rewrite ==-1 )
3812         {
3813                 if(direct)
3814                         writeSelectFooter(message,str,analyze,analyze->call_part);
3815                 else
3816                         writeSelectFooter(message,str,analyze,SELECT_FROMCLAUSE);
3817
3818                 message->rewritelock = -1;
3819         }
3820 }
3821
3822 static void
3823 initAggexpr(AnalyzeSelect *analyze)
3824 {
3825         Aggexpr *agg;
3826
3827         if(analyze->aggexpr)
3828                 return;
3829
3830         analyze->aggexpr = (Aggexpr *) palloc(sizeof(Aggexpr));
3831         agg = analyze->aggexpr;
3832         agg->usec_p = NULL;
3833         agg->tfunc_p = NULL;
3834         agg->col_p = NULL;
3835         agg->hfunc_p = NULL;
3836         agg->umapc = NULL;
3837         agg->u_num = 0;
3838         agg->t_num = 0;
3839         agg->c_num = 0;
3840         agg->h_num = 0;
3841         agg->hc_num = 0;
3842         agg->s_num = 0;
3843         agg->sc_num = 0;
3844         agg->opt = true;
3845 }
3846
3847 static int
3848 FuncChangebyAggregate(AnalyzeSelect *analyze, FuncCall *fnode)
3849 {
3850         Aggexpr *agg;
3851         int i;
3852
3853
3854         if(analyze->aggregate && analyze->aggexpr)
3855                 agg = analyze->aggexpr;
3856         else
3857                 return -1;
3858
3859         if(!agg->opt)
3860                 return -1;
3861
3862         if(analyze->part == SELECT_TARGETLIST)
3863         {
3864                 for(i = 0; i < agg->t_num; i++)
3865                 {
3866                         if(fnode == agg->tfunc_p[i])
3867                         {
3868                                 return i;
3869                         }
3870                 }
3871         }
3872         else if(analyze->part == SELECT_HAVINGCLAUSE)
3873         {
3874                 for(i = 0; i < agg->h_num; i++)
3875                 {
3876                         if(fnode == agg->hfunc_p[i])
3877                         {
3878                                 return i;
3879                         }
3880                 }
3881         }
3882         else if(analyze->part == SELECT_SORTCLAUSE)
3883         {
3884                 String *sortfunc;
3885                 sortfunc = init_string("");
3886                 _outNode(sortfunc, fnode);
3887
3888                 for(i = 0; i < agg->t_num; i++)
3889                 {
3890                         String *having;
3891                         having = init_string("");
3892                         _outNode(having, agg->tfunc_p[i]);
3893                         if(!strcmp(sortfunc->data,having->data))
3894                         {
3895                                 free_string(having);
3896                                 free_string(sortfunc);
3897                                 return i;
3898                         } else {
3899                                 if(having)
3900                                         free_string(having);
3901                         }
3902                 }
3903                 if(sortfunc)
3904                         free_string(sortfunc);
3905         }
3906         return -1;
3907 }
3908
3909 static int
3910 ColumnChangebyAggregate(AnalyzeSelect *analyze,ColumnRef *cnode)
3911 {
3912         Aggexpr *agg;
3913         int i;
3914
3915
3916         if(analyze->aggregate && analyze->aggexpr)
3917                 agg = analyze->aggexpr;
3918         else
3919                 return -1;
3920
3921         if(!agg->opt)
3922                 return -1;
3923
3924         if(analyze->part == SELECT_GROUPBYCLAUSE)
3925         {
3926                 for(i = 0; i < agg->c_num; i++)
3927                 {
3928                         if(cnode == agg->col_p[i])
3929                         {
3930                                 return agg->t_num + i;
3931                         }
3932                 }
3933         }
3934         else if(analyze->part == SELECT_TARGETLIST)
3935         {
3936                 for(i = 0; i < agg->u_num; i++)
3937                 {
3938                         char *n_c = NULL;
3939                         char *n_t = NULL;
3940                         char *c_c = NULL;
3941                         char *c_t = NULL;
3942                         n_c = GetNameFromColumnRef(cnode,true);
3943                         n_t = GetNameFromColumnRef(cnode,false);
3944                         c_c = GetNameFromColumnRef(agg->usec_p[i],true);
3945                         c_t = GetNameFromColumnRef(agg->usec_p[i],false);
3946
3947                         if(n_t && c_t)
3948                         {
3949                                 if(!strcmp(n_t,c_t) && !strcmp(n_c,c_c))
3950                                         return agg->t_num + agg->umapc[i];
3951                         }
3952                         else
3953                         {
3954                                 if(!strcmp(n_c,c_c))
3955                                         return agg->t_num + agg->umapc[i];
3956                         }
3957                 }
3958         }
3959         else if(analyze->part == SELECT_HAVINGCLAUSE || analyze->part == SELECT_SORTCLAUSE)
3960         {
3961                 for(i = 0; i < agg->c_num; i++)
3962                 {
3963                         char *n_c = NULL;
3964                         char *n_t = NULL;
3965                         char *c_c = NULL;
3966                         char *c_t = NULL;
3967                         n_c = GetNameFromColumnRef(cnode,true);
3968                         n_t = GetNameFromColumnRef(cnode,false);
3969                         c_c = GetNameFromColumnRef(agg->col_p[i],true);
3970                         c_t = GetNameFromColumnRef(agg->col_p[i],false);
3971
3972                         if(n_t && c_t)
3973                         {
3974                                 if(!strcmp(n_t,c_t) && !strcmp(n_c,c_c))
3975                                         return agg->t_num + i;
3976                         }
3977                         else
3978                         {
3979                                 if(!strcmp(n_c,c_c))
3980                                         return agg->t_num + i;
3981                         }
3982                 }
3983         }
3984         return -1;
3985 }
3986
3987 static void
3988 AppendAggregate(AnalyzeSelect *analyze,FuncCall *fnode,ColumnRef *cnode)
3989 {
3990         Aggexpr *agg;
3991
3992         initAggexpr(analyze);
3993
3994         agg = analyze->aggexpr;
3995
3996
3997         if(analyze->part == SELECT_GROUPBYCLAUSE)
3998         {
3999                 if(!agg->col_p)
4000                 {
4001                         agg->col_p = (ColumnRef **) palloc(sizeof(ColumnRef *));
4002                 }
4003                 else
4004                 {
4005                         agg->col_p = (ColumnRef **) repalloc(agg->col_p,(agg->c_num + 1) *sizeof(ColumnRef *));
4006                 }
4007                 agg->col_p[agg->c_num] = cnode;
4008                 SeekColumnName(agg,cnode,SELECT_GROUPBYCLAUSE);
4009                 agg->c_num++;
4010         }
4011         else if(analyze->part == SELECT_TARGETLIST)
4012         {
4013                 if(fnode)  /* for function */
4014                 {
4015                         if(!agg->tfunc_p)
4016                         {
4017                                 agg->tfunc_p = (FuncCall **) palloc(sizeof(FuncCall *));
4018                         }
4019                         else
4020                         {
4021                                 agg->tfunc_p = (FuncCall **) repalloc(agg->tfunc_p,(agg->t_num + 1) *sizeof(FuncCall *));
4022                         }
4023                         agg->tfunc_p[agg->t_num] = fnode;
4024                         agg->t_num++;
4025                 } else {   /* for Column */
4026                         if(!agg->usec_p)
4027                         {
4028                                 agg->usec_p = (ColumnRef **) palloc(sizeof(ColumnRef *));
4029                                 agg->umapc = (int *) palloc(sizeof(int));
4030                         }
4031                         else
4032                         {
4033                                 agg->usec_p = (ColumnRef **) repalloc(agg->usec_p,(agg->u_num + 1) *sizeof(ColumnRef *));
4034                                 agg->umapc = (int *) repalloc(agg->umapc,(agg->u_num + 1) *sizeof(int));
4035                         }
4036                         agg->usec_p[agg->u_num] = cnode;
4037                         agg->u_num++;
4038                 }
4039         }
4040         else if(analyze->part == SELECT_HAVINGCLAUSE)
4041         {
4042                 if(fnode)  /* for function */
4043                 {
4044                         if(!agg->hfunc_p)
4045                         {
4046                                 agg->hfunc_p = (FuncCall **) palloc(sizeof(FuncCall *));
4047                         }
4048                         else
4049                         {
4050                                 agg->hfunc_p = (FuncCall **) repalloc(agg->hfunc_p,(agg->h_num + 1) *sizeof(FuncCall *));
4051                         }
4052                         agg->hfunc_p[agg->h_num] = fnode;
4053                         agg->h_num++;
4054                 }
4055         }
4056 }
4057
4058 static void
4059 _rewriteFuncCall(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FuncCall *node)
4060 {
4061         char *funcname;
4062         bool avg_flag = false;
4063         if(message->r_code == SELECT_AEXPR)
4064         {
4065                 KeepRewriteQueryReturnCode(message, SELECT_AEXPR_FALSE);
4066                 return;
4067         }
4068
4069         funcname = strVal(lfirst(list_head(node->funcname)));
4070
4071         if (CheckAggOpt(message))
4072         {
4073                 int i;
4074                 AnalyzeSelect *analyze;
4075                 int no = message->current_select;
4076                 analyze = message->analyze[no];
4077
4078                 i = FuncChangebyAggregate(analyze,node);
4079                 if(i != -1)
4080                 {
4081                         if(!strcmp(funcname,"count"))
4082                                 delay_string_append_char(message, str, "sum");
4083                         else if(!strcmp(funcname,"avg"))
4084                         {
4085                                 delay_string_append_char(message, str, "(sum");
4086                                 avg_flag =true;
4087                         }
4088                         else
4089                                 _rewriteFuncName(BaseSelect, message, dblink, str, node->funcname);
4090                 }
4091                 else
4092                 _rewriteFuncName(BaseSelect, message, dblink, str, node->funcname);
4093
4094         }
4095         else
4096                 _rewriteFuncName(BaseSelect, message, dblink, str, node->funcname);
4097
4098         if(message->r_code == SELECT_ANALYZE && funcname)
4099         {
4100                 /* aggregate functions */
4101                 if(!strcmp(funcname,"count") || !strcmp(funcname,"max") || !strcmp(funcname,"min")
4102                         || !strcmp(funcname,"sum") || !strcmp(funcname,"avg") || !strcmp(funcname,"bit_and")
4103                         || !strcmp(funcname,"bit_or") || !strcmp(funcname,"bool_and") || !strcmp(funcname,"bool_or")
4104                         || !strcmp(funcname,"every") || !strcmp(funcname,"corr") || !strcmp(funcname,"covar_pop")
4105                         || !strcmp(funcname,"covar_samp") || !strcmp(funcname,"regr_avgx") || !strcmp(funcname,"regr_avgy")
4106                         || !strcmp(funcname,"regr_count") || !strcmp(funcname,"regr_intercept") || !strcmp(funcname,"regr_r2")
4107                         || !strcmp(funcname,"regr_slope") || !strcmp(funcname,"regr_sxx") || !strcmp(funcname,"regr_sxy")
4108                         || !strcmp(funcname,"regr_syy") || !strcmp(funcname,"stddev") || !strcmp(funcname,"stddev_pop")
4109                         || !strcmp(funcname,"stddev_samp") || !strcmp(funcname,"variance") || !strcmp(funcname,"var_pop")
4110                         || !strcmp(funcname,"var_samp"))
4111                 {
4112                         AnalyzeSelect *analyze;
4113                         int no = message->current_select;
4114                         analyze = message->analyze[no];
4115                         analyze->aggregate = true;
4116
4117                         if(analyze->part == SELECT_TARGETLIST || analyze->part == SELECT_HAVINGCLAUSE)
4118                         {
4119                                 if(!strcmp(funcname,"count") || !strcmp(funcname,"max") ||
4120                                                 !strcmp(funcname,"min") || !strcmp(funcname,"sum") || !strcmp(funcname,"avg"))
4121                                 {
4122                                         AppendAggregate(analyze,node,NULL);
4123                                 }
4124                                 else
4125                                 {
4126                                         initAggexpr(analyze);
4127                                         analyze->aggexpr->opt = false;
4128                                 }
4129                         }
4130                 }
4131         }
4132
4133         if(strcmp(funcname,"user") == 0 ||
4134            strcmp(funcname,"current_user") == 0 ||
4135            strcmp(funcname,"session_user") == 0 ||
4136            strcmp(funcname,"current_role") == 0)
4137                 return ;
4138
4139         delay_string_append_char(message, str, "(");
4140
4141         if (node->agg_distinct == TRUE)
4142                 delay_string_append_char(message, str, "DISTINCT ");
4143
4144         if (CheckAggOpt(message))
4145         {
4146                 int i;
4147                 AnalyzeSelect *analyze;
4148                 int no = message->current_select;
4149                 analyze = message->analyze[no];
4150                 i = FuncChangebyAggregate(analyze,node);
4151                 if(i != -1)
4152                 {
4153                         char buf[16];
4154                         snprintf(buf, 16, "%d", i);
4155                         delay_string_append_char(message, str, "pool_g$");
4156                         delay_string_append_char(message, str, buf);
4157                         pool_debug("_FuncCall: aggregate no = %d",i);
4158                         delay_string_append_char(message, str, ")");
4159
4160                         if(avg_flag)
4161                         {
4162                                 delay_string_append_char(message, str, "/");
4163                                 delay_string_append_char(message, str, "sum(");
4164                                 delay_string_append_char(message, str, "pool_g$");
4165                                 delay_string_append_char(message, str, buf);
4166                                 delay_string_append_char(message, str, "c");
4167                                 delay_string_append_char(message, str, "))");
4168                         }
4169                         return ;
4170                 }
4171         }
4172
4173         if (node->agg_star == TRUE)
4174                 delay_string_append_char(message, str, "*");
4175         else
4176                 _rewriteNode(BaseSelect, message, dblink, str, node->args);
4177
4178         delay_string_append_char(message, str, ")");
4179 }
4180
4181 static void
4182 AvgFuncCall(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FuncCall *node)
4183 {
4184         char *funcname;
4185         if(message->r_code == SELECT_AEXPR)
4186         {
4187                 KeepRewriteQueryReturnCode(message, SELECT_AEXPR_FALSE);
4188                 return;
4189         }
4190
4191         funcname = strVal(lfirst(list_head(node->funcname)));
4192
4193         delay_string_append_char(message, str, "sum");
4194
4195         delay_string_append_char(message, str, "(");
4196
4197         if (node->agg_distinct == TRUE)
4198                 delay_string_append_char(message, str, "DISTINCT ");
4199
4200         _rewriteNode(BaseSelect, message, dblink, str, node->args);
4201
4202         delay_string_append_char(message, str, ")");
4203         delay_string_append_char(message, str, ",");
4204         delay_string_append_char(message, str, "count");
4205
4206         delay_string_append_char(message, str, "(");
4207
4208         if (node->agg_distinct == TRUE)
4209                 delay_string_append_char(message, str, "DISTINCT ");
4210
4211         _rewriteNode(BaseSelect, message, dblink, str, node->args);
4212
4213         delay_string_append_char(message, str, ")");
4214 }
4215
4216 static void
4217 _rewriteDefElem(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DefElem *node)
4218 {
4219
4220 }
4221
4222 static void
4223 _rewriteLockingClause(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, LockingClause *node)
4224 {
4225         if (node == NULL)
4226                 return;
4227
4228         if (node->forUpdate == TRUE)
4229                 delay_string_append_char(message, str, " FOR UPDATE");
4230         else
4231                 delay_string_append_char(message, str, " FOR SHARED");
4232
4233         _rewriteNode(BaseSelect, message, dblink, str, node->lockedRels);
4234
4235         if (node->noWait == TRUE)
4236                 delay_string_append_char(message, str, " NOWAIT ");
4237 }
4238
4239 static void
4240 _rewriteColumnDef(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ColumnDef *node)
4241 {
4242         delay_string_append_char(message, str, "\"");
4243         delay_string_append_char(message, str, node->colname);
4244         delay_string_append_char(message, str, "\" ");
4245         _rewriteNode(BaseSelect, message, dblink, str, node->typename);
4246         _rewriteNode(BaseSelect, message, dblink, str, node->constraints);
4247 }
4248
4249 static void
4250 _rewriteTypeName(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, TypeName *node)
4251 {
4252         ListCell *lc;
4253         char dot = 0;
4254
4255         foreach (lc, node->names)
4256         {
4257                 Value *v = (Value *) lfirst(lc);
4258                 char *typename = v->val.str;
4259
4260                 if (dot == 0)
4261                         dot = 1;
4262                 else
4263                         delay_string_append_char(message, str, ".");
4264                         if(node->typemod < 0)
4265                         {
4266                                 if(message->rewritelock != -1)
4267                                 {
4268                                         delay_string_append_char(message, str, "\"\"");
4269                                         delay_string_append_char(message, str, typename);
4270                                         delay_string_append_char(message, str, "\"\"");
4271                                 } else {
4272                                         //delay_string_append_char(message, str, "\"");
4273                                         delay_string_append_char(message, str, typename);
4274                                         //delay_string_append_char(message, str, "\"");
4275                                 }
4276                         } else 
4277                                 delay_string_append_char(message, str, typename);
4278         }
4279         
4280         if (node->typemod > 0)
4281         {
4282                 int lower;
4283                 char buf[16];
4284                 delay_string_append_char(message, str, "(");
4285                 snprintf(buf, 16, "%d", ((node->typemod - VARHDRSZ) >> 16) & 0x00FF);
4286                 delay_string_append_char(message, str, buf);
4287                 lower = (node->typemod-VARHDRSZ) & 0x00FF;
4288
4289                 if(lower != 0)
4290                 {
4291                         char buf2[16];
4292                         delay_string_append_char(message, str, ",");
4293                         snprintf(buf2, 16, "%d",lower);
4294                         delay_string_append_char(message, str, buf2);
4295                 }
4296
4297                 delay_string_append_char(message, str, ")");
4298         }
4299 }
4300
4301 static void
4302 _rewriteTypeCast(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, TypeCast *node)
4303 {
4304         _rewriteNode(BaseSelect, message, dblink, str, node->arg);
4305         delay_string_append_char(message, str, "::");
4306         _rewriteNode(BaseSelect, message, dblink, str, node->typename);
4307
4308 }
4309
4310 static void
4311 _rewriteIndexElem(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, IndexElem *node)
4312 {
4313         if (node->name)
4314         {
4315                 delay_string_append_char(message, str, "\"");
4316                 delay_string_append_char(message, str, node->name);
4317                 delay_string_append_char(message, str, "\"");
4318                 if (node->opclass != NIL)
4319                         _rewriteNode(BaseSelect, message, dblink, str, node->opclass);
4320         }
4321         else
4322         {
4323                 delay_string_append_char(message, str, "(");
4324                 _rewriteNode(BaseSelect, message, dblink, str, node->expr);
4325                 delay_string_append_char(message, str, ")");
4326                 if (node->opclass != NIL)
4327                         _rewriteNode(BaseSelect, message, dblink, str, node->opclass);
4328         }
4329 }
4330
4331
4332 static void
4333 _rewriteSortClause(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SortClause *node)
4334 {
4335
4336 }
4337
4338 static void
4339 _rewriteGroupClause(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, GroupClause *node)
4340 {
4341
4342 }
4343
4344 static void
4345 _rewriteSetOperationStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SetOperationStmt *node)
4346 {
4347
4348 }
4349
4350
4351 static void
4352 _rewriteAExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, A_Expr *node)
4353 {
4354         Value *v;
4355
4356         switch (node->kind)
4357         {
4358                 case AEXPR_OP:
4359                         if (list_length(node->name) == 1)
4360                         {
4361                                 Value *op = (Value *) lfirst(list_head(node->name));
4362
4363                                 delay_string_append_char(message, str, " (");
4364                                 _rewriteNode(BaseSelect, message, dblink, str, node->lexpr);
4365                                 delay_string_append_char(message, str, op->val.str);
4366                                 _rewriteNode(BaseSelect, message, dblink, str, node->rexpr);
4367                                 delay_string_append_char(message, str, " )");
4368                         }
4369                         break;
4370
4371                 case AEXPR_AND:
4372                         delay_string_append_char(message, str, " (");
4373                         _rewriteNode(BaseSelect, message, dblink, str, node->lexpr);
4374                         delay_string_append_char(message, str, " AND ");
4375                         _rewriteNode(BaseSelect, message, dblink, str, node->rexpr);
4376                         delay_string_append_char(message, str, ")");
4377                         break;
4378
4379                 case AEXPR_OR:
4380                         delay_string_append_char(message, str, " (");
4381                         _rewriteNode(BaseSelect, message, dblink, str, node->lexpr);
4382                         delay_string_append_char(message, str, " OR ");
4383                         _rewriteNode(BaseSelect, message, dblink, str, node->rexpr);
4384                         delay_string_append_char(message, str, ")");
4385                         break;
4386
4387                 case AEXPR_NOT:
4388                         delay_string_append_char(message, str, " (NOT ");
4389                         _rewriteNode(BaseSelect, message, dblink, str, node->rexpr);
4390                         delay_string_append_char(message, str, ")");
4391                         break;
4392
4393                 case AEXPR_OP_ANY:
4394                         _rewriteNode(BaseSelect,message,dblink,str, node->lexpr);
4395                         v = linitial(node->name);
4396                         delay_string_append_char(message,str, v->val.str);
4397                         delay_string_append_char(message,str, "ANY(");
4398                         _rewriteNode(BaseSelect,message,dblink,str, node->rexpr);
4399                         delay_string_append_char(message,str, ")");
4400                         break;
4401
4402                 case AEXPR_OP_ALL:
4403                         _rewriteNode(BaseSelect,message,dblink,str, node->lexpr);
4404                         v = linitial(node->name);
4405                         delay_string_append_char(message,str, v->val.str);
4406                         delay_string_append_char(message,str, "ALL(");
4407                         _rewriteNode(BaseSelect,message,dblink,str, node->rexpr);
4408                         delay_string_append_char(message,str, ")");
4409                         break;
4410
4411                 case AEXPR_DISTINCT:
4412                         delay_string_append_char(message, str, " (");
4413                         _rewriteNode(BaseSelect, message, dblink, str, node->lexpr);
4414                         delay_string_append_char(message, str, " IS DISTINCT FROM ");
4415                         _rewriteNode(BaseSelect, message, dblink, str, node->rexpr);
4416                         delay_string_append_char(message, str, ")");
4417                         break;
4418
4419                 case AEXPR_NULLIF:
4420                         delay_string_append_char(message, str, " NULLIF(");
4421                         _rewriteNode(BaseSelect, message, dblink, str, node->lexpr);
4422                         delay_string_append_char(message, str, ", ");
4423                         _rewriteNode(BaseSelect, message, dblink, str, node->rexpr);
4424                         delay_string_append_char(message, str, ")");
4425                         break;
4426
4427                 case AEXPR_OF:
4428                         _rewriteNode(BaseSelect, message, dblink, str, node->lexpr);
4429                         v = linitial(node->name);
4430                         if (v->val.str[0] == '!')
4431                                 delay_string_append_char(message, str, " IS NOT OF (");
4432                         else
4433                                 delay_string_append_char(message, str, " IS OF (");
4434                         _rewriteNode(BaseSelect, message, dblink, str, node->rexpr);
4435                         delay_string_append_char(message, str, ")");
4436                         break;
4437                 case AEXPR_IN:
4438                         _rewriteNode(BaseSelect,message,dblink,str, node->lexpr);
4439                         v = (Value *)lfirst(list_head(node->name));
4440                         if (v->val.str[0] == '=')
4441                                 delay_string_append_char(message,str, " IN (");
4442                         else
4443                                 delay_string_append_char(message,str, " NOT IN (");
4444                         _rewriteNode(BaseSelect,message,dblink,str, node->rexpr);
4445                         delay_string_append_char(message,str, ")");
4446                         break;
4447                 default:
4448                         break;
4449         }
4450 }
4451
4452 static void
4453 _rewriteValue(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Value *value)
4454 {
4455         char buf[16];
4456
4457         switch (value->type)
4458         {
4459                 case T_Integer:
4460                         sprintf(buf, "%ld", value->val.ival);
4461                         delay_string_append_char(message, str, buf);
4462                         break;
4463
4464                 case T_Float:
4465                         delay_string_append_char(message, str, value->val.str);
4466                         break;
4467
4468                 case T_String:
4469                         /* delay_string_append_char(message, str, "'"); */
4470                         delay_string_append_char(message, str, escape_string(value->val.str));
4471                         /* delay_string_append_char(message, str, "'"); */
4472                         break;
4473
4474                 case T_Null:
4475                         delay_string_append_char(message, str, "NULL");
4476                         break;
4477
4478                 default:
4479                         break;
4480         }
4481 }
4482
4483 static char
4484 GetInnerRef(RewriteQuery *message,int last,char *table_name,char *column,char state)
4485 {
4486         AnalyzeSelect *analyze;
4487         VirtualTable *virtual;
4488         int num, i;
4489         bool get = false;
4490
4491         analyze = message->analyze[last];
4492         virtual = analyze->virtual;
4493         num = virtual->col_num;
4494
4495         for(i=0; i < num; i++)
4496         {
4497                 char *vcol = virtual->col_list[i];
4498                 char *vtable = virtual->table_list[i];
4499                 if(table_name
4500                         && !strcmp(table_name,vtable) && !strcmp(column,vcol))
4501                 {
4502                         pool_debug("GetInnerRef state = %c now select(%d), table_name=(%s), col_name=(%s) detect",state,last,vtable,vcol);
4503                         get = true;
4504                         break;
4505                 }
4506                 else if(!table_name && !strcmp(column,vcol))
4507                 {
4508                         pool_debug("GetInnerRef state = %c  now select(%d), table_name=(%s), col_name=(%s) detect",state,last,vtable,vcol);
4509                         get = true;
4510                         break;
4511                 }
4512         }
4513
4514         if(get)
4515                 return state;
4516         else
4517         {
4518                 /* there isn't the inner refarence at parallel part */
4519                 if(state == 'P' || analyze->partstate[SELECT_FROMCLAUSE] =='P')
4520                         return 'S';
4521
4522                 if(last == 0)
4523                         return 'E';
4524                 else
4525                         return GetInnerRef(message,analyze->last_select,table_name,column,state);
4526         }
4527 }
4528
4529 static void
4530 ChangeStatebyColumnRef(RewriteQuery *message,ColumnRef *col)
4531 {
4532         AnalyzeSelect *analyze;
4533         VirtualTable *virtual;
4534         ListCell *c;
4535         List *list;
4536         char first = 0;
4537         char *table_name = NULL;
4538         char *column = NULL;
4539         int num,no;
4540
4541         list = col->fields;
4542
4543         no = message->current_select;
4544         analyze = message->analyze[no];
4545
4546         if(list->length > 2 || list->length == 0)
4547         {
4548                 /* Is this error ? */
4549                 message->analyze[no]->state = 'S';
4550                 return;
4551         }
4552
4553         foreach (c, col->fields)
4554         {
4555                 Node *n = (Node *) lfirst(c);
4556
4557                 if (IsA(n, String))
4558                 {
4559                         Value *v = (Value *) lfirst(c);
4560                         if(list->length == 2 && first == 0)
4561                         {
4562                                 first = 1;
4563                                 table_name = v->val.str;
4564                         }
4565                         else
4566                                 column = v->val.str;
4567                 }
4568         }
4569
4570         if(!column)
4571         {
4572                 message->table_state = 'S';
4573                 return;
4574         }
4575
4576         pool_debug("ChangeStatebyColumnRef %s now(%d),last(%d) part(%d) call_part(%d)",
4577                                                         column,
4578                                                         analyze->now_select,
4579                                                         analyze->last_select,
4580                                                         analyze->part,
4581                                                         analyze->call_part
4582                                                         );
4583
4584         virtual = analyze->virtual;
4585         num = virtual->col_num;
4586
4587         if(message->part==SELECT_WHERECLAUSE || message->part == SELECT_TARGETLIST)
4588         {
4589                 if(analyze->partstate[message->part] != 'S')
4590                 {
4591                         analyze->partstate[message->part] =
4592                                 GetInnerRef(message,no,table_name,column,analyze->partstate[SELECT_FROMCLAUSE]);
4593                         pool_debug("return state is %c",analyze->partstate[message->part]);
4594                 }
4595         }
4596 }
4597
4598 static bool DetectValidColumn(RewriteQuery *message,char *table_name,char *column_name,int no, int call)
4599 {
4600         AnalyzeSelect *analyze;
4601         VirtualTable *virtual;
4602         int v_num,i;
4603         int get = 0;
4604         int call_num;
4605         bool star = false;
4606
4607         call_num = message->current_select;
4608
4609         if(call != -1 && no != call_num  && call == SELECT_FROMCLAUSE)
4610         {
4611                 int last = message->analyze[no]->last_select;
4612                 int call_part = message->analyze[no]->call_part;
4613
4614                 if(last == -1)
4615                 {
4616                         return false;
4617                 }
4618                 else
4619                 {
4620                         return DetectValidColumn(message,table_name,column_name,last,call_part);
4621                 }
4622         }
4623
4624         analyze = message->analyze[no];
4625         virtual = analyze->virtual;
4626         v_num = virtual->col_num;
4627
4628         for(i = 0; i< v_num; i++)
4629         {
4630                 char *vcol = virtual->col_list[i];
4631                 char *vtable = virtual->table_list[i];
4632
4633                 if(table_name && !strcmp(table_name,vtable) && !strcmp(column_name,"*"))
4634                 {
4635                         virtual->valid[i] = message->current_select;
4636                         star = true;
4637                 }
4638                 else if (!table_name && !strcmp(column_name,"*"))
4639                 {
4640                         virtual->valid[i] = message->current_select;
4641                         star = true;
4642                 }
4643
4644                 if(table_name
4645                         && !strcmp(table_name,vtable) && !strcmp(column_name,vcol))
4646                 {
4647                         pool_debug("DetectValidColumn no = %d, table_name=(%s), col_name=(%s) detect",no, vtable, vcol);
4648                         get++;
4649
4650                         if(virtual->valid[i] == -1)
4651                         {
4652                                 virtual->valid[i] = message->current_select;
4653                         }
4654                         else if (virtual->valid[i] > no)
4655                         {
4656                                 virtual->valid[i] = message->current_select;
4657                         }
4658                 }
4659                 else if(!table_name && !strcmp(column_name,vcol))
4660                 {
4661                         pool_debug("DetectValidColumn no = %d, col_name=(%s) detect",no, vcol);
4662                         get++;
4663
4664                         if(virtual->valid[i] == -1)
4665                         {
4666                                 virtual->valid[i] = message->current_select;
4667                         }
4668                         else if (virtual->valid[i] > no)
4669                         {
4670                                 virtual->valid[i] = message->current_select;
4671                         }
4672                 }
4673         }
4674
4675         if(star)
4676                 return true;
4677
4678         if(get == 1)
4679         {
4680                 return true;
4681         }
4682         else if(get == 0)
4683         {
4684                 int last = analyze->last_select;
4685                 if(last != -1)
4686                 {
4687                         return DetectValidColumn(message,table_name,column_name,analyze->last_select,analyze->call_part);
4688                 }
4689         }
4690         else if(get>= 2)
4691                 pool_debug("DetectValidColumn select_no=(%d) col_name=(%s) ambiguous",message->current_select,column_name);
4692
4693         return false;
4694 }
4695
4696 static bool GetPoolColumn(RewriteQuery *message,String *str,char *table_name,char *column_name,int no, int call,bool state)
4697 {
4698         AnalyzeSelect *analyze,*analyze_now;
4699         VirtualTable *virtual;
4700         int v_num,i;
4701         int get = 0;
4702         int call_num;
4703         bool star = false;
4704
4705         call_num = message->current_select;
4706
4707         if(call != -1 && no != call_num  && call == SELECT_FROMCLAUSE)
4708         {
4709                 int last = message->analyze[no]->last_select;
4710                 int call_part = message->analyze[no]->call_part;
4711
4712                 if(last == -1)
4713                 {
4714                         return false;
4715                 }
4716                 else
4717                 {
4718                         return GetPoolColumn(message,str,table_name,column_name,last,call_part,state);
4719                 }
4720         }
4721
4722         analyze = message->analyze[no];
4723         analyze_now = message->analyze[call_num];
4724         virtual = analyze->virtual;
4725         v_num = virtual->col_num;
4726
4727         for(i = 0; i< v_num; i++)
4728         {
4729                 char *vcol = virtual->col_list[i];
4730                 char *vtable = virtual->table_list[i];
4731
4732                 if(table_name && !strcmp(table_name,vtable) && !strcmp(column_name,"*"))
4733                 {
4734                         star = true;
4735                         break;
4736                 }
4737                 else if (!table_name && !strcmp(column_name,"*"))
4738                 {
4739                         star = true;
4740                         break;
4741                 }
4742                 
4743                 if(table_name
4744                         && !strcmp(table_name,vtable) && !strcmp(column_name,vcol))
4745                 {
4746                         pool_debug("GetPoolColumn no = %d, table_name=(%s), col_name=(%s) new_colname$%d detect",no, vtable, vcol,i);
4747                         get++;
4748                         break;
4749                 }       
4750                 else if(!table_name && !strcmp(column_name,vcol))
4751                 {
4752                         pool_debug("GetPoolColumn no = %d, col_name=(%s) new_colname=pool_c$%d detect",no, vcol,i);
4753                         get++;
4754                         break;
4755                 }
4756         }
4757
4758         if(star)
4759         {
4760                 if(table_name)
4761                 {
4762                         int first = 0;
4763                         for(i = 0; i < v_num; i++)
4764                         {
4765                                 char buf[16];
4766                                 if(!strcmp(virtual->table_list[i],table_name) && virtual->valid[i] != -1)
4767                                 {
4768                                         if(first == 0)
4769                                                 first = 1;
4770                                         else
4771                                         delay_string_append_char(message, str, ",");
4772
4773           if(message->rewritelock == -1)
4774                                         {
4775                                                 snprintf(buf, 16, "%d", analyze->virtual->column_no[i]);
4776                                                 delay_string_append_char(message, str,"\"pool_c$");
4777                                                 delay_string_append_char(message, str,buf);
4778                                                 delay_string_append_char(message, str, "\"");
4779
4780                                                 if(message->ignore_rewrite == -1 && call_num != 0 && analyze->call_part == SELECT_FROMCLAUSE)
4781                                                 {
4782                                                         char buf2[16];
4783                                                         int col_no = analyze->select_ret->return_list[analyze->ret_count];
4784                                                         delay_string_append_char(message, str, " AS ");
4785                                                         snprintf(buf2, 16, "%d", col_no);
4786                                                         delay_string_append_char(message, str,"\"pool_c$");
4787                                                         delay_string_append_char(message, str,buf2);
4788                                                         delay_string_append_char(message, str, "\"");
4789                                                         delay_string_append_char(message, str," ");
4790                                                         pool_debug("GetPoolColumn analyze[%d] targetlist=* =>  pool_c$%s AS pool_c$%s",
4791                                                                 no,buf,buf2);
4792                                                         analyze->ret_count++;
4793                                                         continue;
4794                                                 }
4795                                         } else {
4796                                                 delay_string_append_char(message, str,analyze->virtual->col_list[i]);
4797                                         }
4798
4799                                         delay_string_append_char(message, str, " ");
4800
4801                                         if(state && message->rewritelock == -1)
4802                                         {
4803                                                 delay_string_append_char(message, str, " AS ");
4804                                                 delay_string_append_char(message, str, "\"");
4805                                                 delay_string_append_char(message, str, analyze->select_ret->col_list[message->ret_num]);
4806                                                 delay_string_append_char(message, str, "\" ");
4807                                                 message->ret_num++;
4808                                         }
4809                                 }
4810                         }
4811                 }
4812                 else
4813                 {
4814                         int first = 0;
4815                         for(i = 0; i < v_num; i++)
4816                         {
4817                                 char buf[16];
4818                                 if(virtual->valid[i] != -1)
4819                                 {
4820                                         if(first == 0)
4821                                                 first = 1;
4822                                         else
4823                                         delay_string_append_char(message, str, ",");
4824
4825                                         if(message->rewritelock == -1)
4826                                         {
4827                                                 snprintf(buf, 16, "%d", analyze->virtual->column_no[i]);
4828                                                 delay_string_append_char(message, str,"\"pool_c$");
4829                                                 delay_string_append_char(message, str,buf); 
4830                                                 delay_string_append_char(message, str,"\"");
4831
4832                                                 if(message->ignore_rewrite == -1 && call_num != 0 && analyze->call_part == SELECT_FROMCLAUSE)
4833                                                 {
4834                                                         char buf2[16];
4835                                                         int col_no = analyze->select_ret->return_list[analyze->ret_count];
4836                                                         delay_string_append_char(message, str, " AS ");
4837                                                         snprintf(buf2, 16, "%d", col_no);
4838                                                         delay_string_append_char(message, str,"\"pool_c$");
4839                                                         delay_string_append_char(message, str,buf2);
4840                                                         delay_string_append_char(message, str,"\"");
4841                                                         delay_string_append_char(message, str," ");
4842                                                         analyze->ret_count++;
4843                                                         pool_debug("GetPoolColumn analyze[%d] targetlist=%s =>  pool_c$%s AS pool_c$%s",
4844                                                                 no,column_name,buf,buf2);
4845                                                         continue;
4846                                                 }
4847
4848                                         } else {
4849                                                 delay_string_append_char(message, str,analyze->virtual->col_list[i]);
4850                                         }
4851                                         delay_string_append_char(message, str, " ");
4852
4853                                         if(state && message->rewritelock == -1)
4854                                         {
4855                                                 delay_string_append_char(message, str, " AS ");
4856                                                 delay_string_append_char(message, str, analyze->select_ret->col_list[message->ret_num]);
4857                                                 message->ret_num++;
4858                                         }
4859                                 }
4860                         }
4861                 }
4862                 return true;
4863         }
4864
4865         if(get == 1)
4866         {
4867                 char buf[16];
4868                 snprintf(buf, 16, "%d", virtual->column_no[i]);
4869
4870 #if 0
4871                 if(analyze_now->partstate[SELECT_FROMCLAUSE] != 'S') {
4872                         delay_string_append_char(message, str, analyze->table_name);
4873                         delay_string_append_char(message, str, ".");
4874                 } else {
4875                         delay_string_append_char(message, str, virtual->table_list[i]);
4876                         delay_string_append_char(message, str, ".");
4877                 }
4878 #endif
4879                 delay_string_append_char(message, str, "\"pool_c$");
4880                 delay_string_append_char(message, str, buf);
4881                 delay_string_append_char(message, str, "\"");
4882
4883                 return true;
4884         }
4885         else if(get == 0)
4886         {
4887                 int last = analyze->last_select;
4888                 if(last != -1)
4889                 {
4890                         return GetPoolColumn(message,str,table_name,column_name,analyze->last_select,analyze->call_part,state);
4891                 }
4892                 else
4893                         return false;
4894         }
4895
4896         return false;
4897 }
4898
4899 static void SeekColumnName(Aggexpr *agg,ColumnRef *node, int state)
4900 {
4901         char *column = NULL;
4902         char *table = NULL;
4903         int i;
4904
4905         /* get column & table name from group by */
4906         column = GetNameFromColumnRef(node,true);
4907         table = GetNameFromColumnRef(node,false);
4908
4909         if(state == SELECT_GROUPBYCLAUSE)
4910         {
4911                 for(i = 0; i < agg->u_num; i++)
4912                 {
4913                         ColumnRef *unode = agg->usec_p[i];
4914                         char *t_column = NULL;
4915                         char *t_table = NULL;
4916                         t_column = GetNameFromColumnRef(unode,true);
4917                         t_table = GetNameFromColumnRef(unode,false);
4918
4919                         if(table && t_table)
4920                         {
4921                                 if(!strcmp(table,t_table) && !strcmp(column,t_column))
4922                                 {
4923                                         agg->umapc[i] = agg->c_num;
4924                                         return;
4925                                 }
4926                         }
4927                         else
4928                         {
4929                                 if(!strcmp(column,t_column))
4930                                 {
4931                                         agg->umapc[i] = agg->c_num;
4932                                         return;
4933                                 }
4934                         }
4935                 }
4936         }
4937 }
4938
4939 static bool CheckAggOpt(RewriteQuery *message)
4940 {
4941         AnalyzeSelect *analyze;
4942         if(message->r_code != SELECT_DEFAULT)
4943                 return false;
4944
4945         analyze = message->analyze[message->current_select];
4946
4947         if(analyze->aggregate && analyze->aggexpr && analyze->aggexpr->opt
4948                         && (analyze->part == SELECT_TARGETLIST || analyze->part == SELECT_GROUPBYCLAUSE
4949                                 || analyze->part == SELECT_HAVINGCLAUSE || analyze->part == SELECT_SORTCLAUSE)
4950                         && analyze->partstate[SELECT_FROMCLAUSE] == 'P'
4951                         && analyze->partstate[SELECT_TARGETLIST] == 'S'
4952                         && analyze->partstate[SELECT_WHERECLAUSE] == 'P')
4953                 return true;
4954
4955         return false;
4956 }
4957
4958 static char *GetNameFromColumnRef(ColumnRef *node,bool state)
4959 {
4960         ListCell *c;
4961         List *list;
4962         list = node->fields;
4963         int first = 0;
4964         char *table_name = NULL;
4965   char *column_name = NULL;
4966
4967         foreach (c, node->fields)
4968         {
4969                 Node *n = (Node *) lfirst(c);
4970
4971                 if (IsA(n, String))
4972                 {
4973                         Value *v = (Value *) lfirst(c);
4974                         if(list->length == 2 && first == 0)
4975                         {
4976                                 first = 1;
4977                                 table_name = v->val.str;
4978                         }
4979                         else
4980                                 column_name = v->val.str;
4981                 }
4982         }
4983
4984         if(state)
4985                 return column_name;
4986         else
4987                 return table_name;
4988 }
4989
4990 static void
4991 _rewriteColumnRef(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ColumnRef *node)
4992 {
4993         ListCell *c;
4994         List *list;
4995         char first = 0;
4996         char *table_name = NULL;
4997   char *column_name = NULL;
4998
4999         if(CheckAggOpt(message))
5000         {
5001                 int i;
5002                 AnalyzeSelect *analyze = message->analyze[message->current_select];
5003
5004                 i = ColumnChangebyAggregate(analyze,node);
5005                 if(i != -1)
5006                 {
5007                  char buf[16];
5008                  snprintf(buf, 16, "%d", i);
5009                  delay_string_append_char(message, str, "pool_g$");
5010                  delay_string_append_char(message, str, buf);
5011                  pool_debug("_rewriteColumnRef: aggregate no = %d",i);
5012                  return ;
5013                 }
5014         }
5015
5016         list = node->fields;
5017
5018         foreach (c, node->fields)
5019         {
5020                 Node *n = (Node *) lfirst(c);
5021
5022                 if (IsA(n, String))
5023                 {
5024
5025                         if(message->r_code == SELECT_AEXPR &&
5026                                 (_checkVirtualColumn(node, message) != 1))
5027                         {
5028                                 KeepRewriteQueryReturnCode(message, SELECT_AEXPR_FALSE);
5029                                 return;
5030                         }
5031
5032                         Value *v = (Value *) lfirst(c);
5033                         if(list->length == 2 && first == 0)
5034                         {
5035                                 first = 1;
5036                                 table_name = v->val.str;
5037                         }
5038                         else
5039                                 column_name = v->val.str;
5040                 }
5041         }
5042
5043         if(message->r_code == SELECT_ANALYZE)
5044         {
5045                 AnalyzeSelect *analyze = message->analyze[message->current_select];
5046
5047                 if(analyze->part == SELECT_GROUPBYCLAUSE || analyze->part == SELECT_TARGETLIST)
5048                         AppendAggregate(analyze,NULL,node);
5049
5050                 if(!DetectValidColumn(message,table_name,column_name,message->current_select,-1))
5051                 {
5052                         message->is_loadbalance = true;
5053                         pool_debug("_rewriteColumnRef: wrong column select_no=%d",message->current_select);
5054                 }
5055                 if(strcmp(column_name,"*"))
5056                                 ChangeStatebyColumnRef(message,node);
5057         }
5058         else if(message->r_code == SELECT_DEFAULT)
5059         {
5060
5061                 if(message->rewritelock == -1)
5062                 {
5063                         if(!GetPoolColumn(message,str,table_name,column_name,message->current_select,-1,false))
5064                                 delay_string_append_char(message, str, column_name);
5065                 }
5066                 else
5067                 {
5068                         if(table_name)
5069                         {
5070                                 if(message->rewritelock == -1)
5071                                 {
5072                                         AnalyzeSelect *analyze = message->analyze[message->current_select];
5073                                         char s = analyze->partstate[SELECT_FROMCLAUSE];
5074
5075                                         if(s == 'L' || s =='P')
5076                                         {
5077                                                 delay_string_append_char(message, str, analyze->table_name);
5078                                         }
5079                                 }
5080                                 else
5081                                         delay_string_append_char(message, str, table_name);
5082                                 delay_string_append_char(message, str, ".");
5083                         }
5084                         delay_string_append_char(message, str, column_name);
5085                 }
5086         }
5087 }
5088
5089 static void
5090 _rewriteParamRef(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ParamRef *node)
5091 {
5092         char buf[16];
5093
5094         snprintf(buf, 16, "%d", node->number);
5095         delay_string_append_char(message, str, "$");
5096         delay_string_append_char(message, str, buf);
5097 }
5098
5099 static void
5100 _rewriteAConst(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, A_Const *node)
5101 {
5102         char buf[16];
5103         char *name = NULL;
5104
5105         if (node->typename)
5106         {
5107                 Value *v = linitial(node->typename->names);
5108                 name = v->val.str;
5109                 _rewriteNode(BaseSelect, message, dblink, str, node->typename);
5110                 delay_string_append_char(message, str, " ");
5111         }
5112
5113         switch (node->val.type)
5114         {
5115                 case T_Integer:
5116                         sprintf(buf, "%ld", node->val.val.ival);
5117                         delay_string_append_char(message, str, buf);
5118                         break;
5119
5120                 case T_Float:
5121                         delay_string_append_char(message, str, node->val.val.str);
5122                         break;
5123
5124                 case T_String:
5125                         if(message->rewritelock != -1)
5126                         {
5127                                 delay_string_append_char(message, str, "\'\'");
5128                                 delay_string_append_char(message, str, escape_string(node->val.val.str));
5129                                 delay_string_append_char(message, str, "\'\'");
5130                         } else {
5131                                 delay_string_append_char(message, str, "\'");
5132                                 delay_string_append_char(message, str, escape_string(node->val.val.str));
5133                                 delay_string_append_char(message, str, "\'");
5134                         }
5135                         break;
5136
5137                 case T_Null:
5138                         delay_string_append_char(message, str, "NULL");
5139                         break;
5140
5141                 default:
5142                         break;
5143         }
5144
5145         if (name && (strcmp(name, "interval") == 0) &&
5146           node->typename->typmods)
5147         {
5148                 A_Const *v = linitial(node->typename->typmods);
5149                 int mask = v->val.val.ival;
5150
5151                 if (mask == INTERVAL_MASK(YEAR))
5152                         delay_string_append_char(message, str, " YEAR");
5153                 else if (mask == INTERVAL_MASK(MONTH))
5154                         delay_string_append_char(message, str, " MONTH");
5155                 else if (mask == INTERVAL_MASK(DAY))
5156                         delay_string_append_char(message, str, " DAY");
5157                 else if (mask == INTERVAL_MASK(HOUR))
5158                         delay_string_append_char(message, str, " HOUR");
5159                 else if (mask == INTERVAL_MASK(MINUTE))
5160                         delay_string_append_char(message, str, " MINUTE");
5161                 else if (mask == INTERVAL_MASK(SECOND))
5162                         delay_string_append_char(message, str, " SECOND");
5163                 else if (mask == (INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH)))
5164                         delay_string_append_char(message, str, " YEAR TO MONTH");
5165                 else if (mask == (INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR)))
5166                         delay_string_append_char(message, str, " DAY TO HOUR");
5167                 else if (mask == (INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) |
5168                                 INTERVAL_MASK(MINUTE)))
5169                         delay_string_append_char(message, str, " DAY TO MINUTE");
5170                 else if (mask == (INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) |
5171                                 INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND)))
5172                         delay_string_append_char(message, str, " DAY TO SECOND");
5173                 else if (mask == (INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE)))
5174                         delay_string_append_char(message, str, " HOUR TO MINUTE");
5175                 else if (mask == (INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) |
5176                                 INTERVAL_MASK(SECOND)))
5177                         delay_string_append_char(message, str, " HOUR TO SECOND");
5178   }
5179 }
5180
5181 static void
5182 _rewriteA_Indices(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, A_Indices *node)
5183 {
5184         delay_string_append_char(message, str, "[");
5185         if (node->lidx)
5186         {
5187                 _rewriteNode(BaseSelect, message, dblink, str, node->lidx);
5188                 delay_string_append_char(message, str, ":");
5189         }
5190         _rewriteNode(BaseSelect, message, dblink, str, node->uidx);
5191         delay_string_append_char(message, str, "]");
5192 }
5193
5194 static void
5195 _rewriteA_Indirection(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, A_Indirection *node)
5196 {
5197         _rewriteNode(BaseSelect, message, dblink, str, node->arg);
5198         _rewriteNode(BaseSelect, message, dblink, str, node->indirection);
5199
5200 }
5201
5202 static bool
5203 AliasToResTargetCondition(RewriteQuery *message,String *str)
5204 {
5205         int select_no = message->current_select;
5206         AnalyzeSelect *n_analyze;
5207         AnalyzeSelect *u_analyze;
5208         char buf[16];
5209         int ret;
5210         int col_no;
5211
5212         if(select_no == 0 || message->r_code != SELECT_DEFAULT
5213                         || message->rewritelock != -1 || message->ignore_rewrite != -1)
5214                 return false;
5215
5216         n_analyze=message->analyze[select_no];
5217         u_analyze=message->analyze[select_no - 1];
5218
5219         if(n_analyze->call_part == SELECT_FROMCLAUSE)
5220         {
5221                 ret = n_analyze->ret_count;
5222                 col_no = n_analyze->select_ret->return_list[n_analyze->ret_count];
5223                 pool_debug("AliasToResTargetCondition select no =%d,ret_no = %d,col_no =%d,colname=%s", select_no,ret,col_no,n_analyze->select_ret->col_list[ret]);
5224                 delay_string_append_char(message, str, " AS ");
5225                 snprintf(buf, 16, "%d", col_no);
5226                 delay_string_append_char(message, str,"\"pool_c$");
5227                 delay_string_append_char(message, str,buf);
5228                 delay_string_append_char(message, str,"\"");
5229                 delay_string_append_char(message, str," ");
5230                 return true;
5231         }
5232         else if(u_analyze->select_union && u_analyze->call_part == SELECT_FROMCLAUSE)
5233         {
5234                 ret = u_analyze->ret_count;
5235                 col_no = u_analyze->select_ret->return_list[u_analyze->ret_count];
5236                 pool_debug("AliasToResTargetCondition(union) select now=%d up=%d,ret_no = %d,col_no =%d,colname=%s", select_no,select_no-1,ret,col_no,u_analyze->select_ret->col_list[ret]);
5237                 delay_string_append_char(message, str, " AS ");
5238                 snprintf(buf, 16, "%d", col_no);
5239                 delay_string_append_char(message, str,"\"pool_c$");
5240                 delay_string_append_char(message, str,buf);
5241                 delay_string_append_char(message, str,"\"");
5242                 delay_string_append_char(message, str," ");
5243                 u_analyze->ret_count++;
5244                 return true;
5245         }
5246         else
5247                 return false;
5248 }
5249
5250 static void
5251 _rewriteResTarget(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ResTarget *node)
5252 {
5253         int select_no = message->current_select;
5254         AnalyzeSelect *analyze = NULL;
5255         SelectDefInfo *select = NULL;
5256
5257         if(message->r_code == SELECT_DEFAULT)
5258         {
5259                 analyze= message->analyze[select_no];
5260                 select = analyze->select_ret;
5261         }
5262
5263         if (node->indirection != NIL)
5264         {
5265                 delay_string_append_char(message, str, "\"");
5266                 delay_string_append_char(message, str, node->name);
5267                 delay_string_append_char(message, str, "\"=");
5268                 _rewriteNode(BaseSelect, message, dblink, str, node->val);
5269         }
5270         else
5271         {
5272                 char *star = NULL;
5273                 char *table_name = NULL;
5274
5275                 if(message->r_code == SELECT_DEFAULT && !node->name)
5276                 {
5277                         if (node->val && (IsA(node->val, ColumnRef)))
5278                         {
5279                                 int first = 0;
5280                                 ListCell *c;
5281                                 ColumnRef *col;
5282
5283                                 col = (ColumnRef *) node->val;
5284                                 foreach (c, col->fields)
5285                                 {
5286                                         Node *n = (Node *) lfirst(c);
5287
5288                                         if (IsA(n, String))
5289                                         {
5290                                                 Value *v = (Value *) lfirst(c);
5291                                                 if(col->fields->length == 2 && first == 0)
5292                                                 {
5293                                                         first = 1;
5294                                                         table_name = v->val.str;
5295                                                 }
5296                                                 else
5297                                                         star = v->val.str;
5298                                         }
5299                                 }
5300                         }
5301
5302                         if(star && strcmp(star,"*"))
5303                         {
5304                                 star = NULL;
5305                         }
5306                 }
5307
5308                 if(select_no == 0 && star)
5309                 {
5310                                 GetPoolColumn(message,str,table_name,star,message->current_select,-1,true);
5311                                 return;
5312                 }
5313                 else
5314                 {
5315                         _rewriteNode(BaseSelect, message, dblink, str, node->val);
5316                         if(star)
5317                                 return;
5318                 }
5319
5320                 if(AliasToResTargetCondition(message,str))
5321                         return;
5322
5323                 if (node->name)
5324                 {
5325                         delay_string_append_char(message, str, " AS ");
5326                         delay_string_append_char(message, str, node->name);
5327                         if(message->r_code == SELECT_DEFAULT && select_no == 0)
5328                                 message->ret_num++;
5329                         return;
5330                 }
5331                 else if(message->r_code == SELECT_DEFAULT && select_no == 0
5332                                         && !node->name)
5333                 {
5334                         char *col_name = select->col_list[message->ret_num];
5335                         pool_debug("_rewriteResTarget: check(%d) ret_num=%d",message->current_select,message->ret_num);
5336                         pool_debug("_rewriteResTarget: col ret_num=%d col_name=%s",message->current_select,col_name);
5337                         delay_string_append_char(message, str, " AS ");
5338                         delay_string_append_char(message, str, col_name);
5339
5340                         message->ret_num++;
5341                 }
5342         }
5343 }
5344
5345 static void
5346 _rewriteConstraint(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, Constraint *node)
5347 {
5348         if (node->name)
5349         {
5350                 delay_string_append_char(message, str, "CONSTRAINT \"");
5351                 delay_string_append_char(message, str, node->name);
5352                 delay_string_append_char(message, str, "\"");
5353         }
5354
5355         switch (node->contype)
5356         {
5357                 case CONSTR_CHECK:
5358                         delay_string_append_char(message, str, " CHECK (");
5359                         _rewriteNode(BaseSelect, message, dblink, str, node->raw_expr);
5360                         delay_string_append_char(message, str, ")");
5361                         break;
5362
5363                 case CONSTR_UNIQUE:
5364                         delay_string_append_char(message, str, " UNIQUE");
5365                         if (node->keys)
5366                         {
5367                                 delay_string_append_char(message, str, "(");
5368                                 _rewriteIdList(BaseSelect, message, dblink, str, node->keys);
5369                                 delay_string_append_char(message, str, ")");
5370                         }
5371
5372                         if (node->indexspace)
5373                         {
5374                                 delay_string_append_char(message, str, " USING INDEX TABLESPACE \"");
5375                                 delay_string_append_char(message, str, node->indexspace);
5376                                 delay_string_append_char(message, str, "\"");
5377                         }
5378                         break;
5379
5380                 case CONSTR_PRIMARY:
5381                         delay_string_append_char(message, str, " PRIMARY KEY");
5382                         if (node->keys)
5383                         {
5384                                 delay_string_append_char(message, str, "(");
5385                                 _rewriteIdList(BaseSelect, message, dblink, str, node->keys);
5386                                 delay_string_append_char(message, str, ")");
5387                         }
5388                         if (node->indexspace)
5389                         {
5390                                 delay_string_append_char(message, str, " USING INDEX TABLESPACE \"");
5391                                 delay_string_append_char(message, str, node->indexspace);
5392                                 delay_string_append_char(message, str, "\"");
5393                         }
5394                         break;
5395
5396                 case CONSTR_NOTNULL:
5397                         delay_string_append_char(message, str, " NOT NULL");
5398                         break;
5399
5400                 case CONSTR_NULL:
5401                         delay_string_append_char(message, str, " NULL");
5402                         break;
5403
5404                 case CONSTR_DEFAULT:
5405                         delay_string_append_char(message, str, "DEFAULT ");
5406                         _rewriteNode(BaseSelect, message, dblink, str, node->raw_expr);
5407                         break;
5408
5409                 default:
5410                         break;
5411         }
5412 }
5413
5414 static void
5415 _rewriteFkConstraint(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FkConstraint *node)
5416 {
5417         if (node->constr_name)
5418         {
5419                 delay_string_append_char(message, str, "CONSTRAINT \"");
5420                 delay_string_append_char(message, str, node->constr_name);
5421                 delay_string_append_char(message, str, "\"");
5422         }
5423
5424         if (node->fk_attrs != NIL)
5425         {
5426                 delay_string_append_char(message, str, " FOREIGN KEY (");
5427                 _rewriteIdList(BaseSelect, message, dblink, str, node->fk_attrs);
5428                 delay_string_append_char(message, str, ")" );
5429         }
5430
5431         delay_string_append_char(message, str, " REFERENCES ");
5432         _rewriteNode(BaseSelect, message, dblink, str, node->pktable);
5433
5434         if (node->pk_attrs != NIL)
5435         {
5436                 delay_string_append_char(message, str, "(");
5437                 _rewriteIdList(BaseSelect, message, dblink, str, node->pk_attrs);
5438                 delay_string_append_char(message, str, ")");
5439         }
5440
5441         switch (node->fk_matchtype)
5442         {
5443                 case FKCONSTR_MATCH_FULL:
5444                         delay_string_append_char(message, str, " MATCH FULL");
5445                         break;
5446
5447                 case FKCONSTR_MATCH_PARTIAL:
5448                         delay_string_append_char(message, str, " MATCH PARTIAL");
5449                         break;
5450
5451                 default:
5452                         break;
5453         }
5454
5455         switch (node->fk_upd_action)
5456         {
5457                 case FKCONSTR_ACTION_RESTRICT:
5458                         delay_string_append_char(message, str, " ON UPDATE RESTRICT");
5459                         break;
5460
5461                 case FKCONSTR_ACTION_CASCADE:
5462                         delay_string_append_char(message, str, " ON UPDATE CASCADE");
5463                         break;
5464
5465                 case FKCONSTR_ACTION_SETNULL:
5466                         delay_string_append_char(message, str, " ON UPDATE SET NULL");
5467                         break;
5468
5469                 case FKCONSTR_ACTION_SETDEFAULT:
5470                         delay_string_append_char(message, str, " ON UPDATE SET DEFAULT");
5471                         break;
5472
5473                 default:
5474                         break;
5475         }
5476
5477         switch (node->fk_del_action)
5478         {
5479                 case FKCONSTR_ACTION_RESTRICT:
5480                         delay_string_append_char(message, str, " ON DELETE RESTRICT");
5481                         break;
5482
5483                 case FKCONSTR_ACTION_CASCADE:
5484                         delay_string_append_char(message, str, " ON DELETE CASCADE");
5485                         break;
5486
5487                 case FKCONSTR_ACTION_SETNULL:
5488                         delay_string_append_char(message, str, " ON DELETE SET NULL");
5489                         break;
5490
5491                 case FKCONSTR_ACTION_SETDEFAULT:
5492                         delay_string_append_char(message, str, " ON DELETE SET DEFAULT");
5493                         break;
5494
5495                 default:
5496                         break;
5497         }
5498
5499         if (node->deferrable)
5500                 delay_string_append_char(message, str, " DEFERRABLE");
5501
5502         if (node->initdeferred)
5503                 delay_string_append_char(message, str, " INITIALLY DEFERRED");
5504 }
5505
5506
5507 static void
5508 _rewriteSortBy(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, SortBy *node)
5509 {
5510         _rewriteNode(BaseSelect, message, dblink, str, node->node);
5511
5512         if (node->sortby_dir == SORTBY_USING)
5513         {
5514                 delay_string_append_char(message, str, " USING ");
5515                 _rewriteNode(BaseSelect, message, dblink, str, node->useOp);
5516         }
5517         else if (node->sortby_dir == SORTBY_DESC)
5518                 delay_string_append_char(message, str, " DESC ");
5519
5520         if (node->sortby_nulls == SORTBY_NULLS_FIRST)
5521                 delay_string_append_char(message, str, " NULLS FIRST ");
5522         else if (node->sortby_nulls == SORTBY_NULLS_LAST)
5523                 delay_string_append_char(message, str, " NULLS LAST ");
5524 }
5525
5526 static void _rewriteInsertStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, InsertStmt *node)
5527 {
5528         delay_string_append_char(message, str, "INSERT INTO ");
5529         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
5530
5531         if (node->cols == NIL && node->selectStmt == NULL)
5532                 delay_string_append_char(message, str, " DEFAULT VALUES");
5533
5534         if (node->cols)
5535         {
5536                 char comma = 0;
5537                 ListCell *lc;
5538
5539                 delay_string_append_char(message, str, "(");
5540
5541                 foreach (lc, node->cols)
5542                 {
5543                         ResTarget *node = lfirst(lc);
5544                         if (comma == 0)
5545                                 comma = 1;
5546                         else
5547                                 delay_string_append_char(message, str, ", ");
5548
5549                         delay_string_append_char(message, str, "\"");
5550                         delay_string_append_char(message, str, node->name);
5551                         delay_string_append_char(message, str, "\"");
5552                 }
5553                 delay_string_append_char(message, str, ")");
5554         }
5555
5556         if (node->selectStmt)
5557         {
5558                 _rewriteNode(BaseSelect, message, dblink, str, node->selectStmt);
5559         }
5560
5561         if (node->returningList)
5562         {
5563                 delay_string_append_char(message, str, " RETURNING ");
5564                 _rewriteNode(BaseSelect, message, dblink, str, node->returningList);
5565         }
5566 }
5567
5568 static void _rewriteUpdateStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, UpdateStmt *node)
5569 {
5570         ListCell *lc;
5571         char comma = 0;
5572
5573         delay_string_append_char(message, str, "UPDATE ");
5574
5575         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
5576
5577         delay_string_append_char(message, str, " SET ");
5578         foreach (lc, node->targetList)
5579         {
5580                 ResTarget *node = lfirst(lc);
5581                 if (comma == 0)
5582                         comma = 1;
5583                 else
5584                         delay_string_append_char(message, str, ", ");
5585
5586                 delay_string_append_char(message, str, "\"");
5587                 delay_string_append_char(message, str, node->name);
5588                 delay_string_append_char(message, str, "\" =");
5589                 _rewriteNode(BaseSelect, message, dblink, str, node->val);
5590         }
5591
5592         if (node->fromClause)
5593         {
5594                 delay_string_append_char(message, str, " FROM ");
5595                 _rewriteNode(BaseSelect, message, dblink, str, node->fromClause);
5596         }
5597
5598         if (node->whereClause)
5599         {
5600                 delay_string_append_char(message, str, " WHERE ");
5601                 _rewriteNode(BaseSelect, message, dblink, str, node->whereClause);
5602         }
5603
5604         if (node->returningList)
5605         {
5606                 delay_string_append_char(message, str, " RETURNING ");
5607                 _rewriteNode(BaseSelect, message, dblink, str, node->returningList);
5608         }
5609 }
5610
5611 static void _rewriteDeleteStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DeleteStmt *node)
5612 {
5613         delay_string_append_char(message, str, "DELETE FROM ");
5614
5615         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
5616
5617         if (node->usingClause)
5618         {
5619                 delay_string_append_char(message, str, " USING ");
5620                 _rewriteNode(BaseSelect, message, dblink, str, node->usingClause);
5621         }
5622
5623         if (node->whereClause)
5624         {
5625                 delay_string_append_char(message, str, " WHERE ");
5626                 _rewriteNode(BaseSelect, message, dblink, str, node->whereClause);
5627         }
5628
5629         if (node->returningList)
5630         {
5631                 delay_string_append_char(message, str, " RETURNING ");
5632                 _rewriteNode(BaseSelect, message, dblink, str, node->returningList);
5633         }
5634 }
5635
5636 static void _rewriteTransactionStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, TransactionStmt *node)
5637 {
5638         switch (node->kind)
5639         {
5640                 case TRANS_STMT_BEGIN:
5641                         delay_string_append_char(message, str, "BEGIN ");
5642                         break;
5643
5644                 case TRANS_STMT_START:
5645                         delay_string_append_char(message, str, "START TRANSACTION ");
5646                         break;
5647
5648                 case TRANS_STMT_COMMIT:
5649                         delay_string_append_char(message, str, "COMMIT ");
5650                         break;
5651
5652                 case TRANS_STMT_ROLLBACK:
5653                         delay_string_append_char(message, str, "ABORT ");
5654                         break;
5655
5656                 case TRANS_STMT_SAVEPOINT:
5657                         delay_string_append_char(message, str, "SAVEPOINT ");
5658                         break;
5659
5660                 case TRANS_STMT_RELEASE:
5661                         delay_string_append_char(message, str, "RELEASE ");
5662                         break;
5663
5664                 case TRANS_STMT_ROLLBACK_TO:
5665                         delay_string_append_char(message, str, "ROLLBACK TO ");
5666                         break;
5667
5668                 case TRANS_STMT_PREPARE:
5669                         delay_string_append_char(message, str, "PREPARE TRANSACTION ");
5670                         break;
5671
5672                 case TRANS_STMT_COMMIT_PREPARED:
5673                         delay_string_append_char(message, str, "COMMIT PREPARED ");
5674                         break;
5675
5676                 case TRANS_STMT_ROLLBACK_PREPARED:
5677                         delay_string_append_char(message, str, "ROLLBACK PREPARED ");
5678                         break;
5679
5680                 default:
5681                         break;
5682         }
5683
5684         if (node->options)
5685                 _rewriteSetTransactionModeList(BaseSelect, message, dblink, str, node->options);
5686
5687         if (node->gid)
5688                 delay_string_append_char(message, str, node->gid);
5689 }
5690
5691
5692 static void _rewriteTruncateStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, TruncateStmt *node)
5693 {
5694         delay_string_append_char(message, str, "TRUNCATE ");
5695         _rewriteNode(BaseSelect, message, dblink, str, node->relations);
5696 }
5697
5698 static void _rewriteVacuumStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, VacuumStmt *node)
5699 {
5700         if (node->vacuum == true)
5701                 delay_string_append_char(message, str, "VACUUM ");
5702         else
5703                 delay_string_append_char(message, str, "ANALYZE ");
5704
5705         if (node->full == TRUE)
5706                 delay_string_append_char(message, str, "FULL ");
5707
5708         if (node->freeze_min_age == 0)
5709                 delay_string_append_char(message, str, "FREEZE ");
5710
5711         if (node->verbose == TRUE)
5712                 delay_string_append_char(message, str, "VERBOSE ");
5713
5714         if (node->analyze)
5715                 delay_string_append_char(message, str, "ANALYZE ");
5716
5717         _rewriteNode(BaseSelect, message, dblink, str, node->va_cols);
5718 }
5719
5720 static void _rewriteExplainStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ExplainStmt *node)
5721 {
5722         delay_string_append_char(message, str, "EXPLAIN ");
5723
5724         if (node->analyze == TRUE)
5725                 delay_string_append_char(message, str, "ANALYZE ");
5726         if (node->verbose == TRUE)
5727                 delay_string_append_char(message, str, "VERBOSE ");
5728
5729         _rewriteNode(BaseSelect, message, dblink, str, node->query);
5730 }
5731
5732 static void _rewriteClusterStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ClusterStmt *node)
5733 {
5734         delay_string_append_char(message, str, "CLUSTER ");
5735
5736         if (node->indexname)
5737         {
5738                 delay_string_append_char(message, str, "\"");
5739                 delay_string_append_char(message, str, node->indexname);
5740                 delay_string_append_char(message, str, "\" ON ");
5741         }
5742         if (node->relation)
5743                 _rewriteNode(BaseSelect, message, dblink, str, node->relation);
5744 }
5745
5746 static void _rewriteCheckPointStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CheckPointStmt *node)
5747 {
5748         delay_string_append_char(message, str, "CHECKPOINT");
5749 }
5750
5751 static void _rewriteClosePortalStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ClosePortalStmt *node)
5752 {
5753         delay_string_append_char(message, str, "CLOSE ");
5754         delay_string_append_char(message, str, "\"");
5755         delay_string_append_char(message, str, node->portalname);
5756         delay_string_append_char(message, str, "\"");
5757 }
5758
5759 static void _rewriteListenStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ListenStmt *node)
5760 {
5761         delay_string_append_char(message, str, "LISTEN ");
5762         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
5763 }
5764
5765 static void _rewriteUnlistenStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, UnlistenStmt *node)
5766 {
5767         delay_string_append_char(message, str, "UNLISTEN ");
5768         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
5769 }
5770
5771 static void _rewriteLoadStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, LoadStmt *node)
5772 {
5773         delay_string_append_char(message, str, "LOAD '");
5774         delay_string_append_char(message, str, node->filename);
5775         delay_string_append_char(message, str, "'");
5776 }
5777
5778 static void _rewriteCopyStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CopyStmt *node)
5779 {
5780         int binary = FALSE;
5781         int oids = FALSE;
5782         char *delimiter = NULL;
5783         char *null = NULL;
5784         int csv = FALSE;
5785         int header = FALSE;
5786         char *quote = NULL;
5787         char *escape = NULL;
5788         Node *force_quote = NULL;
5789         Node *force_notnull = NULL;
5790         ListCell *lc;
5791
5792         foreach (lc, node->attlist)
5793         {
5794                 DefElem *e = lfirst(lc);
5795
5796                 if (strcmp(e->defname, "binary") == 0)
5797                         binary = TRUE;
5798                 else if (strcmp(e->defname, "oids") == 0)
5799                         oids = TRUE;
5800                 else if (strcmp(e->defname, "delimiter") == 0)
5801                         delimiter = ((Value *) e->arg)->val.str;
5802                 else if (strcmp(e->defname, "null") == 0)
5803                         null = ((Value *) e->arg)->val.str;
5804                 else if (strcmp(e->defname, "csv") == 0)
5805                         csv = TRUE;
5806                 else if (strcmp(e->defname, "header") == 0)
5807                         header = TRUE;
5808                 else if (strcmp(e->defname, "quote") == 0)
5809                         quote = ((Value *) e->arg)->val.str;
5810                 else if (strcmp(e->defname, "escape") == 0)
5811                         escape = ((Value *) e->arg)->val.str;
5812                 else if (strcmp(e->defname, "force_quote") == 0)
5813                         force_quote = e->arg;
5814                 else if (strcmp(e->defname, "force_notnull") == 0)
5815                         force_notnull = e->arg;
5816         }
5817
5818         delay_string_append_char(message, str, "COPY ");
5819
5820         if (node->query)
5821         {
5822                 delay_string_append_char(message, str, "(");
5823                 _rewriteNode(BaseSelect, message, dblink, str, node->query);
5824                 delay_string_append_char(message, str, ")");
5825         }
5826
5827         if (binary == TRUE)
5828                 delay_string_append_char(message, str, "BINARY ");
5829
5830         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
5831
5832         if (node->attlist)
5833         {
5834                 delay_string_append_char(message, str, "(");
5835                 _rewriteNode(BaseSelect, message, dblink, str, node->attlist);
5836                 delay_string_append_char(message, str, ") ");
5837         }
5838
5839         if (oids == TRUE)
5840                 delay_string_append_char(message, str, " OIDS ");
5841
5842         if (node->is_from == TRUE)
5843                 delay_string_append_char(message, str, " FROM ");
5844         else
5845                 delay_string_append_char(message, str, " TO ");
5846
5847         if (node->filename)
5848         {
5849                 delay_string_append_char(message, str, "'");
5850                 delay_string_append_char(message, str, node->filename);
5851                 delay_string_append_char(message, str, "'");
5852         }
5853         else
5854                 delay_string_append_char(message, str, node->is_from == TRUE ? "STDIN" : "STDOUT");
5855
5856         if (delimiter)
5857         {
5858                 delay_string_append_char(message, str, " DELIMITERS '");
5859                 delay_string_append_char(message, str, delimiter);
5860                 delay_string_append_char(message, str, "'");
5861         }
5862
5863         if (null)
5864         {
5865                 delay_string_append_char(message, str, "NULL '");
5866                 delay_string_append_char(message, str, null);
5867                 delay_string_append_char(message, str, "' ");
5868         }
5869
5870         if (csv == TRUE)
5871                 delay_string_append_char(message, str, "CSV ");
5872
5873         if (header == TRUE)
5874                 delay_string_append_char(message, str, "HEADER ");
5875
5876         if (quote)
5877         {
5878                 delay_string_append_char(message, str, "QUOTE '");
5879                 delay_string_append_char(message, str, quote);
5880                 delay_string_append_char(message, str, "' ");
5881         }
5882
5883         if (escape)
5884         {
5885                 delay_string_append_char(message, str, "ESCAPE '");
5886                 delay_string_append_char(message, str, escape);
5887                 delay_string_append_char(message, str, "' ");
5888         }
5889
5890         if (force_quote)
5891         {
5892                 delay_string_append_char(message, str, "FORCE QUOTE ");
5893                 _rewriteNode(BaseSelect, message, dblink, str, force_quote);
5894         }
5895
5896         if (force_notnull)
5897         {
5898                 delay_string_append_char(message, str, " FORCE NOT NULL ");
5899                 _rewriteNode(BaseSelect, message, dblink, str, force_notnull);
5900         }
5901 }
5902
5903 static void _rewriteDeallocateStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DeallocateStmt *node)
5904 {
5905         delay_string_append_char(message, str, "DEALLOCATE \"");
5906         delay_string_append_char(message, str, node->name);
5907         delay_string_append_char(message, str, "\"");
5908 }
5909
5910 static void _rewriteRenameStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RenameStmt *node)
5911 {
5912         ListCell *lc;
5913         char comma = 0;
5914
5915         delay_string_append_char(message, str, "ALTER ");
5916
5917         switch (node->renameType)
5918         {
5919                 case OBJECT_AGGREGATE:
5920                         delay_string_append_char(message, str, "AGGREGATE ");
5921                         _rewriteNode(BaseSelect, message, dblink, str, node->object);
5922                         delay_string_append_char(message, str, " (");
5923                         delay_string_append_char(message, str, ") RENAME TO \"");
5924                         delay_string_append_char(message, str, node->newname);
5925                         delay_string_append_char(message, str, "\"");
5926                         break;
5927
5928                 case OBJECT_CONVERSION:
5929                         delay_string_append_char(message, str, "CONVERSION ");
5930                         _rewriteNode(BaseSelect, message, dblink, str, node->object);
5931                         delay_string_append_char(message, str, " RENAME TO \"");
5932                         delay_string_append_char(message, str, node->newname);
5933                         delay_string_append_char(message, str, "\"");
5934                         break;
5935
5936                 case OBJECT_DATABASE:
5937                         delay_string_append_char(message, str, "DATABASE \"");
5938                         delay_string_append_char(message, str, node->subname);
5939                         delay_string_append_char(message, str, "\" RENAME TO \"");
5940                         delay_string_append_char(message, str, node->newname);
5941                         delay_string_append_char(message, str, "\"");
5942                         break;
5943
5944                 case OBJECT_FUNCTION:
5945                         delay_string_append_char(message, str, "FUNCTION ");
5946
5947                         foreach (lc, node->object)
5948                         {
5949                                 Node *n = lfirst(lc);
5950                                 if (IsA(n, String))
5951                                 {
5952                                         Value *value = (Value *) n;
5953                                         if (comma == 0)
5954                                                 comma = 1;
5955                                         else
5956                                                 delay_string_append_char(message, str, ".");
5957                                         delay_string_append_char(message, str, "\"");
5958                                         delay_string_append_char(message, str, value->val.str);
5959                                         delay_string_append_char(message, str, "\"");
5960                                 }
5961                                 else
5962                                         _rewriteNode(BaseSelect, message, dblink, str, n);
5963                         }
5964
5965                         delay_string_append_char(message, str, "(");
5966                         _rewriteNode(BaseSelect, message, dblink, str, node->objarg);
5967                         delay_string_append_char(message, str, ")");
5968                         delay_string_append_char(message, str, " RENAME TO \"");
5969                         delay_string_append_char(message, str, node->newname);
5970                         delay_string_append_char(message, str, "\"");
5971                         break;
5972
5973                 case OBJECT_ROLE:
5974                         delay_string_append_char(message, str, "ROLE \"");
5975                         delay_string_append_char(message, str, node->subname);
5976                         delay_string_append_char(message, str, "\" RENAME TO \"");
5977                         delay_string_append_char(message, str, node->newname);
5978                         delay_string_append_char(message, str, "\"");
5979                         break;
5980
5981                 case OBJECT_LANGUAGE:
5982                         delay_string_append_char(message, str, "LANGUAGE \"");
5983                         delay_string_append_char(message, str, node->subname);
5984                         delay_string_append_char(message, str, "\" RENAME TO \"");
5985                         delay_string_append_char(message, str, node->newname);
5986                         delay_string_append_char(message, str, "\"");
5987                         break;
5988
5989                 case OBJECT_OPCLASS:
5990                         delay_string_append_char(message, str, "OPERATOR CLASS ");
5991                         _rewriteNode(BaseSelect, message, dblink, str, node->object);
5992                         delay_string_append_char(message, str, " USING ");
5993                         delay_string_append_char(message, str, node->subname);
5994                         delay_string_append_char(message, str, " RENAME TO \"");
5995                         delay_string_append_char(message, str, node->newname);
5996                         delay_string_append_char(message, str, "\"");
5997                         break;
5998
5999                 case OBJECT_SCHEMA:
6000                         delay_string_append_char(message, str, "SCHEMA \"");
6001                         delay_string_append_char(message, str, node->subname);
6002                         delay_string_append_char(message, str, "\" RENAME TO \"");
6003                         delay_string_append_char(message, str, node->newname);
6004                         delay_string_append_char(message, str, "\"");
6005                         break;
6006
6007                 case OBJECT_TABLE:
6008                         delay_string_append_char(message, str, "TABLE ");
6009                         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
6010                         delay_string_append_char(message, str, " RENAME TO \"");
6011                         delay_string_append_char(message, str, node->newname);
6012                         delay_string_append_char(message, str, "\"");
6013                         break;
6014
6015                 case OBJECT_INDEX:
6016                         delay_string_append_char(message, str, "INDEX ");
6017                         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
6018                         delay_string_append_char(message, str, " RENAME TO \"");
6019                         delay_string_append_char(message, str, node->newname);
6020                         delay_string_append_char(message, str, "\"");
6021                         break;
6022
6023                 case OBJECT_COLUMN:
6024                         delay_string_append_char(message, str, "TABLE ");
6025                         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
6026                         delay_string_append_char(message, str, " RENAME \"");
6027                         delay_string_append_char(message, str, node->subname);
6028                         delay_string_append_char(message, str, "\" TO \"");
6029                         delay_string_append_char(message, str, node->newname);
6030                         delay_string_append_char(message, str, "\"");
6031                         break;
6032
6033                 case OBJECT_TRIGGER:
6034                         delay_string_append_char(message, str, "TRIGGER \"");
6035                         delay_string_append_char(message, str, node->subname);
6036                         delay_string_append_char(message, str, "\" ON ");
6037                         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
6038                         delay_string_append_char(message, str, " RENAME TO \"");
6039                         delay_string_append_char(message, str, node->newname);
6040                         delay_string_append_char(message, str, "\"");
6041                         break;
6042
6043                 case OBJECT_TABLESPACE:
6044                         delay_string_append_char(message, str, "TABLESPACE \"");
6045                         delay_string_append_char(message, str, node->subname);
6046                         delay_string_append_char(message, str, "\" RENAME TO \"");
6047                         delay_string_append_char(message, str, node->newname);
6048                         delay_string_append_char(message, str, "\"");
6049                         break;
6050
6051                 default:
6052                         break;
6053         }
6054 }
6055
6056 static void
6057 _rewriteOptRoleList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *options)
6058 {
6059         ListCell *lc;
6060
6061         foreach (lc, options)
6062         {
6063                 DefElem *elem = lfirst(lc);
6064                 Value *value = (Value *) elem->arg;
6065
6066                 if (strcmp(elem->defname, "password") == 0)
6067                 {
6068                         if (value == NULL)
6069                                 delay_string_append_char(message, str, " PASSWORD NULL");
6070                         else
6071                         {
6072                                 delay_string_append_char(message, str, " PASSWORD '");
6073                                 delay_string_append_char(message, str, value->val.str);
6074                                 delay_string_append_char(message, str, "'");
6075                         }
6076                 }
6077                 else if (strcmp(elem->defname, "encryptedPassword") == 0)
6078                 {
6079                         delay_string_append_char(message, str, " ENCRYPTED PASSWORD '");
6080                         delay_string_append_char(message, str, value->val.str);
6081                         delay_string_append_char(message, str, "'");
6082                 }
6083                 else if (strcmp(elem->defname, "unencryptedPassword") == 0)
6084                 {
6085                         delay_string_append_char(message, str, " UNENCRYPTED PASSWORD '");
6086                         delay_string_append_char(message, str, value->val.str);
6087                         delay_string_append_char(message, str, "'");
6088                 }
6089                 else if (strcmp(elem->defname, "superuser") == 0)
6090                 {
6091                         if (value->val.ival == TRUE)
6092                                 delay_string_append_char(message, str, " SUPERUSER");
6093                         else
6094                                 delay_string_append_char(message, str, " NOSUPERUSER");
6095                 }
6096                 else if (strcmp(elem->defname, "inherit") == 0)
6097                 {
6098                         if (value->val.ival == TRUE)
6099                                 delay_string_append_char(message, str, " INHERIT");
6100                         else
6101                                 delay_string_append_char(message, str, " NOINHERIT");
6102                 }
6103                 else if (strcmp(elem->defname, "createdb") == 0)
6104                 {
6105                         if (value->val.ival == TRUE)
6106                                 delay_string_append_char(message, str, " CREATEDB");
6107                         else
6108                                 delay_string_append_char(message, str, " NOCREATEDB");
6109                 }
6110                 else if (strcmp(elem->defname, "createrole") == 0)
6111                 {
6112                         if (value->val.ival == TRUE)
6113                                 delay_string_append_char(message, str, " CREATEROLE");
6114                         else
6115                                 delay_string_append_char(message, str, " NOCREATEROLE");
6116                 }
6117                 else if (strcmp(elem->defname, "canlogin") == 0)
6118                 {
6119                         if (value->val.ival == TRUE)
6120                                 delay_string_append_char(message, str, " LOGIN");
6121                         else
6122                                 delay_string_append_char(message, str, " NOLOGIN");
6123                 }
6124                 else if (strcmp(elem->defname, "connectionlimit") == 0)
6125                 {
6126                         char buf[16];
6127
6128                         delay_string_append_char(message, str, " CONNECTION LIMIT ");
6129                         snprintf(buf, 16, "%ld", value->val.ival);
6130                         delay_string_append_char(message, str, buf);
6131                 }
6132                 else if (strcmp(elem->defname, "validUntil") == 0)
6133                 {
6134                         delay_string_append_char(message, str, " VALID UNTIL '");
6135                         delay_string_append_char(message, str, value->val.str);
6136                         delay_string_append_char(message, str, "'");
6137                 }
6138                 else if (strcmp(elem->defname, "rolemembers") == 0)
6139                 {
6140                         delay_string_append_char(message, str, " ROLE ");
6141                         _rewriteIdList(BaseSelect, message, dblink, str, (List *) elem->arg);
6142                 }
6143                 else if (strcmp(elem->defname, "sysid") == 0)
6144                 {
6145                         char buf[16];
6146
6147                         delay_string_append_char(message, str, " SYSID ");
6148                         snprintf(buf, 16, "%ld", value->val.ival);
6149                         delay_string_append_char(message, str, buf);
6150                 }
6151                 else if (strcmp(elem->defname, "adminmembers") == 0)
6152                 {
6153                         delay_string_append_char(message, str, " ADMIN ");
6154                         _rewriteIdList(BaseSelect, message, dblink, str, (List *) elem->arg);
6155                 }
6156                 else if (strcmp(elem->defname, "addroleto") == 0)
6157                 {
6158                         delay_string_append_char(message, str, " IN ROLE ");
6159                         _rewriteIdList(BaseSelect, message, dblink, str, (List *) elem->arg);
6160                 }
6161         }
6162 }
6163
6164 static void
6165 _rewriteCreateRoleStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateRoleStmt *node)
6166 {
6167         delay_string_append_char(message, str, "CREATE ");
6168         switch (node->stmt_type)
6169         {
6170                 case ROLESTMT_ROLE:
6171                         delay_string_append_char(message, str, "ROLE \"");
6172                         break;
6173
6174                 case ROLESTMT_USER:
6175                         delay_string_append_char(message, str, "USER \"");
6176                         break;
6177
6178                 case ROLESTMT_GROUP:
6179                         delay_string_append_char(message, str, "GROUP \"");
6180                         break;
6181         }
6182         delay_string_append_char(message, str, node->role);
6183         delay_string_append_char(message, str, "\"");
6184
6185         _rewriteOptRoleList(BaseSelect, message, dblink, str, node->options);
6186 }
6187
6188 static void
6189 _rewriteAlterRoleStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterRoleStmt *node)
6190 {
6191         delay_string_append_char(message, str, "ALTER ROLE \"");
6192         delay_string_append_char(message, str, node->role);
6193         delay_string_append_char(message, str, "\"");
6194         if (node->options)
6195                 _rewriteOptRoleList(BaseSelect, message, dblink, str, node->options);
6196 }
6197
6198 static void
6199 _rewriteAlterRoleSetStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterRoleSetStmt *node)
6200 {
6201         delay_string_append_char(message, str, "ALTER ROLE \"");
6202         delay_string_append_char(message, str, node->role);
6203         delay_string_append_char(message, str, "\" ");
6204
6205         if (node->setstmt)
6206         {
6207                 _rewriteNode(BaseSelect, message, dblink, str, node->setstmt);
6208         }
6209 }
6210
6211
6212 static void
6213 _rewriteSetTransactionModeList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *list)
6214 {
6215         ListCell *lc;
6216         char comma = 0;
6217
6218         foreach (lc, list)
6219         {
6220                 DefElem *elem = lfirst(lc);
6221
6222                 if (comma == 0)
6223                         comma = 1;
6224                 else
6225                         delay_string_append_char(message, str, ",");
6226
6227                 if (strcmp(elem->defname, "transaction_isolation") == 0)
6228                 {
6229                         A_Const *v = (A_Const *) elem->arg;
6230                         delay_string_append_char(message, str, " ISOLATION LEVEL ");
6231                         delay_string_append_char(message, str, v->val.val.str);
6232                 }
6233                 else if (strcmp(elem->defname, "transaction_read_only") == 0)
6234                 {
6235                         A_Const *n = (A_Const *) elem->arg;
6236                         if (n->val.val.ival == TRUE)
6237                                 delay_string_append_char(message, str, "READ ONLY ");
6238                         else
6239                                 delay_string_append_char(message, str, "READ WRITE ");
6240                 }
6241         }
6242 }
6243
6244
6245 static void
6246 _rewriteSetRest(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, VariableSetStmt *node)
6247 {
6248         if (strcmp(node->name, "timezone") == 0)
6249         {
6250                 delay_string_append_char(message, str, "TIME ZONE ");
6251                 if (node->kind != VAR_RESET)
6252                         _rewriteNode(BaseSelect, message, dblink, str, node->args);
6253         }
6254         else if (strcmp(node->name, "TRANSACTION") == 0)
6255         {
6256                 delay_string_append_char(message, str, "TRANSACTION ");
6257                 _rewriteSetTransactionModeList(BaseSelect, message, dblink, str, node->args);
6258         }
6259         else if (strcmp(node->name, "SESSION CHARACTERISTICS") == 0)
6260         {
6261                 delay_string_append_char(message, str, "SESSION CHARACTERISTICS AS TRANSACTION ");
6262                 _rewriteSetTransactionModeList(BaseSelect, message, dblink, str, node->args);
6263         }
6264         else if (strcmp(node->name, "role") == 0)
6265         {
6266                 delay_string_append_char(message, str, "ROLE ");
6267                 if (node->kind != VAR_RESET)
6268                         _rewriteNode(BaseSelect, message, dblink, str, node->args);
6269         }
6270         else if (strcmp(node->name, "session_authorization") == 0)
6271         {
6272                 delay_string_append_char(message, str, "SESSION AUTHORIZATION ");
6273                 if (node->args == NIL && node->kind != VAR_RESET)
6274                         delay_string_append_char(message, str, "DEFAULT");
6275                 else
6276                         _rewriteNode(BaseSelect, message, dblink, str, node->args);
6277         }
6278         else if (strcmp(node->name, "transaction_isolation") == 0)
6279         {
6280                 delay_string_append_char(message, str, "TRANSACTION ISOLATION LEVEL");
6281                 if (node->kind != VAR_RESET)
6282                         _rewriteSetTransactionModeList(BaseSelect, message, dblink, str, node->args);
6283         }
6284         else if (strcmp(node->name, "xmloption") == 0)
6285         {
6286                 A_Const *v = linitial(node->args);
6287                 delay_string_append_char(message, str, "XML OPTOIN ");
6288                 delay_string_append_char(message, str, v->val.val.str);
6289         }
6290         else
6291         {
6292                 delay_string_append_char(message, str, node->name);
6293                 if (node->kind != VAR_RESET)
6294                 {
6295                         if (node->kind == VAR_SET_CURRENT)
6296                         {
6297                                 delay_string_append_char(message, str, " FROM CURRENT");
6298                         }
6299                         else
6300                         {
6301                                 delay_string_append_char(message, str, " TO ");
6302                                 if (node->args == NULL)
6303                                 {
6304                                         delay_string_append_char(message, str, "DEFAULT");
6305                                 }
6306                                 else
6307                                         _rewriteNode(BaseSelect, message, dblink, str, node->args);
6308                         }
6309                 }
6310         }
6311 }
6312
6313 static void
6314 _rewriteDropRoleStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropRoleStmt *node)
6315 {
6316         delay_string_append_char(message, str, "DROP ROLE ");
6317         if (node->missing_ok == TRUE)
6318                 delay_string_append_char(message, str, "IF EXISTS ");
6319         _rewriteIdList(BaseSelect, message, dblink, str, node->roles);
6320 }
6321
6322 static void
6323 _rewriteCreateSchemaStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateSchemaStmt *node)
6324 {
6325         delay_string_append_char(message, str, "CREATE SCHEMA \"");
6326         delay_string_append_char(message, str, node->schemaname);
6327         delay_string_append_char(message, str, "\"");
6328         if (node->authid)
6329         {
6330                 delay_string_append_char(message, str, "AUTHORIZATION \"");
6331                 delay_string_append_char(message, str, node->authid);
6332                 delay_string_append_char(message, str, "\" ");
6333         }
6334         _rewriteNode(BaseSelect, message, dblink, str, node->schemaElts);
6335 }
6336
6337 static void
6338 _rewriteVariableSetStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, VariableSetStmt *node)
6339 {
6340         if (node->kind == VAR_RESET_ALL)
6341         {
6342                 delay_string_append_char(message, str, "RESET ALL");
6343                 return;
6344         }
6345
6346         if (node->kind == VAR_RESET)
6347                 delay_string_append_char(message, str, "RESET ");
6348         else
6349                 delay_string_append_char(message, str, "SET ");
6350
6351         if (node->is_local)
6352                 delay_string_append_char(message, str, "LOCAL ");
6353
6354         _rewriteSetRest(BaseSelect, message, dblink, str, node);
6355 }
6356
6357 static void
6358 _rewriteVariableShowStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, VariableShowStmt *node)
6359 {
6360         if (strcmp(node->name, "timezone") == 0)
6361                 delay_string_append_char(message, str, "SHOW TIME ZONE");
6362         else if (strcmp(node->name, "transaction_isolation") == 0)
6363                 delay_string_append_char(message, str, "SHOW TRANSACTION ISOLATION LEVEL");
6364         else if (strcmp(node->name, "session_authorization") == 0)
6365                 delay_string_append_char(message, str, "SHOW SESSION AUTHORIZATION");
6366         else if (strcmp(node->name, "all") == 0)
6367                 delay_string_append_char(message, str, "SHOW ALL");
6368         else
6369         {
6370                 delay_string_append_char(message, str, "SHOW ");
6371                 delay_string_append_char(message, str, node->name);
6372         }
6373 }
6374
6375 static void
6376 _rewriteConstraintsSetStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ConstraintsSetStmt *node)
6377 {
6378         delay_string_append_char(message, str, "SET CONSTRAINTS ");
6379
6380         if (node->constraints == NIL)
6381                 delay_string_append_char(message, str, "ALL");
6382         else
6383                 _rewriteNode(BaseSelect, message, dblink, str, node->constraints);
6384
6385         delay_string_append_char(message, str, node->deferred == TRUE ? " DEFERRED" : " IMMEDIATE");
6386 }
6387
6388 static void
6389 _rewriteAlterTableCmd(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterTableCmd *node)
6390 {
6391         char buf[16];
6392
6393         switch (node->subtype)
6394         {
6395                 case AT_AddColumn:
6396                         delay_string_append_char(message, str, "ADD ");
6397                         _rewriteNode(BaseSelect, message, dblink, str, node->def);
6398                         break;
6399
6400                 case AT_ColumnDefault:
6401                         delay_string_append_char(message, str, "ALTER \"");
6402                         delay_string_append_char(message, str, node->name);
6403                         delay_string_append_char(message, str, "\" ");
6404                         if (node->def == NULL)
6405                                 delay_string_append_char(message, str, "DROP DEFAULT");
6406                         else
6407                         {
6408                                 delay_string_append_char(message, str, "SET DEFAULT ");
6409                                 _rewriteNode(BaseSelect, message, dblink, str, node->def);
6410                         }
6411                         break;
6412
6413                 case AT_DropNotNull:
6414                         delay_string_append_char(message, str, "ALTER \"");
6415                         delay_string_append_char(message, str, node->name);
6416                         delay_string_append_char(message, str, "\" DROP NOT NULL");
6417                         break;
6418
6419                 case AT_SetNotNull:
6420                         delay_string_append_char(message, str, "ALTER \"");
6421                         delay_string_append_char(message, str, node->name);
6422                         delay_string_append_char(message, str, "\" SET NOT NULL");
6423                         break;
6424
6425                 case AT_SetStatistics:
6426                         delay_string_append_char(message, str, "ALTER \"");
6427                         delay_string_append_char(message, str, node->name);
6428                         delay_string_append_char(message, str, "\" SET STATISTICS ");
6429                         snprintf(buf, 16, "%ld", ((Value *) node->def)->val.ival);
6430                         delay_string_append_char(message, str, buf);
6431                         break;
6432
6433                 case AT_SetStorage:
6434                         delay_string_append_char(message, str, "ALTER \"");
6435                         delay_string_append_char(message, str, node->name);
6436                         delay_string_append_char(message, str, "\" SET STORAGE ");
6437                         delay_string_append_char(message, str, ((Value *) node->def)->val.str);
6438                         break;
6439
6440                 case AT_DropColumn:
6441                         delay_string_append_char(message, str, "DROP \"");
6442                         delay_string_append_char(message, str, node->name);
6443                         delay_string_append_char(message, str, "\" ");
6444                         if (node->behavior == DROP_CASCADE)
6445                                 delay_string_append_char(message, str, "CASCADE");
6446                         break;
6447
6448                 case AT_AlterColumnType:
6449                         delay_string_append_char(message, str, "ALTER \"");
6450                         delay_string_append_char(message, str, node->name);
6451                         delay_string_append_char(message, str, "\" TYPE ");
6452                         _rewriteNode(BaseSelect, message, dblink, str, node->def);
6453                         if (node->transform)
6454                         {
6455                                 delay_string_append_char(message, str, " USING ");
6456                                 _rewriteNode(BaseSelect, message, dblink, str, node->transform);
6457                         }
6458                         break;
6459
6460                 case AT_AddConstraint:
6461                         delay_string_append_char(message, str, "ADD ");
6462                         _rewriteNode(BaseSelect, message, dblink, str, node->def);
6463                         break;
6464
6465                 case AT_DropConstraint:
6466                         delay_string_append_char(message, str, "DROP CONSTRAINT \"");
6467                         delay_string_append_char(message, str, node->name);
6468                         delay_string_append_char(message, str, "\"");
6469                         if (node->behavior == DROP_CASCADE)
6470                                 delay_string_append_char(message, str, " CASCADE");
6471                         break;
6472
6473                 case AT_DropOids:
6474                         delay_string_append_char(message, str, "SET WITHOUT OIDS");
6475                         break;
6476
6477                 case AT_ClusterOn:
6478                         delay_string_append_char(message, str, "CLUSTER ON \"");
6479                         delay_string_append_char(message, str, node->name);
6480                         delay_string_append_char(message, str, "\"");
6481                         break;
6482
6483                 case AT_EnableAlwaysTrig:
6484                         /* not implemented */
6485                         break;
6486
6487                 case AT_EnableReplicaTrig:
6488                         /* not implemented */
6489                         break;
6490
6491                 case AT_DropCluster:
6492                         delay_string_append_char(message, str, "SET WITHOUT CLUSTER");
6493                         break;
6494
6495                 case AT_EnableTrig:
6496                         delay_string_append_char(message, str, "ENABLE TRIGGER \"");
6497                         delay_string_append_char(message, str, node->name);
6498                         delay_string_append_char(message, str, "\"");
6499                         break;
6500
6501                 case AT_EnableTrigAll:
6502                         delay_string_append_char(message, str, "ENABLE TRIGGER ALL");
6503                         break;
6504
6505                 case AT_EnableRule:
6506                         /* not implemented */
6507                         break;
6508
6509                 case AT_EnableReplicaRule:
6510                         /* not implemented */
6511                         break;
6512
6513                 case AT_EnableAlwaysRule:
6514                         /* not implemented */
6515                         break;
6516
6517                 case AT_DisableRule:
6518                         /* not implemented */
6519                         break;
6520
6521                 case AT_AddInherit:
6522                         /* not implemented */
6523                         break;
6524
6525                 case AT_EnableTrigUser:
6526                         delay_string_append_char(message, str, "ENABLE TRIGGER USER");
6527                         break;
6528
6529                 case AT_DisableTrig:
6530                         delay_string_append_char(message, str, "DISABLE TRIGGER \"");
6531                         delay_string_append_char(message, str, node->name);
6532                         delay_string_append_char(message, str, "\"");
6533                         break;
6534
6535                 case AT_DisableTrigAll:
6536                         delay_string_append_char(message, str, "DISABLE TRIGGER ALL");
6537                         break;
6538
6539                 case AT_DisableTrigUser:
6540                         delay_string_append_char(message, str, "DISABLE TRIGGER USER");
6541                         break;
6542
6543                 case AT_ChangeOwner:
6544                         delay_string_append_char(message, str, "OWNER TO \"");
6545                         delay_string_append_char(message, str, node->name);
6546                         delay_string_append_char(message, str, "\"");
6547                         break;
6548
6549                 case AT_SetTableSpace:
6550                         delay_string_append_char(message, str, "SET TABLESPACE \"");
6551                         delay_string_append_char(message, str, node->name);
6552                         delay_string_append_char(message, str, "\"");
6553                         break;
6554
6555                 case AT_SetRelOptions:
6556                         /* not implemented */
6557                         break;
6558
6559                 case AT_ResetRelOptions:
6560                         /* not implemented */
6561                         break;
6562
6563                 default:
6564                         break;
6565         }
6566 }
6567
6568 static void
6569 _rewriteAlterTableStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterTableStmt *node)
6570 {
6571         if (node->relkind == OBJECT_TABLE)
6572                 delay_string_append_char(message, str, "ALTER TABLE ");
6573         else
6574                 delay_string_append_char(message, str, "ALTER INDEX ");
6575
6576         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
6577         delay_string_append_char(message, str, " ");
6578         _rewriteNode(BaseSelect, message, dblink, str, node->cmds);
6579 }
6580
6581 static void
6582 _rewriteOptSeqList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *options)
6583 {
6584         ListCell *lc;
6585
6586         foreach (lc, options)
6587         {
6588                 DefElem *e = lfirst(lc);
6589                 Value *v = (Value *)e->arg;
6590                 char buf[16];
6591
6592                 if (strcmp(e->defname, "cycle") == 0)
6593                 {
6594                         if (v->val.ival == TRUE)
6595                                 delay_string_append_char(message, str, " CYCLE");
6596                         else
6597                                 delay_string_append_char(message, str, " NO CYCLE");
6598                 }
6599                 else if (strcmp(e->defname, "minvalue") == 0 && !v)
6600                         delay_string_append_char(message, str, " NO MINVALUE");
6601                 else if (strcmp(e->defname, "maxvalue") == 0 && !v)
6602                         delay_string_append_char(message, str, " NO MAXVALUE");
6603                 else if (strcmp(e->defname, "owned_by") == 0)
6604                 {
6605                         delay_string_append_char(message, str, " OWNED BY ");
6606                         _rewriteIdList(BaseSelect, message, dblink, str, (List *)e->arg);
6607                 }
6608                 else
6609                 {
6610                         if (strcmp(e->defname, "cache") == 0)
6611                                 delay_string_append_char(message, str, " CACHE ");
6612                         else if (strcmp(e->defname, "increment") == 0)
6613                                 delay_string_append_char(message, str, " INCREMENT ");
6614                         else if (strcmp(e->defname, "maxvalue") == 0 && v)
6615                                 delay_string_append_char(message, str, " MAXVALUE ");
6616                         else if (strcmp(e->defname, "minvalue") == 0 && v)
6617                                 delay_string_append_char(message, str, " MINVALUE ");
6618                         else if (strcmp(e->defname, "start") == 0)
6619                                 delay_string_append_char(message, str, " START ");
6620                         else if (strcmp(e->defname, "restart") == 0)
6621                                 delay_string_append_char(message, str, " RESTART ");
6622
6623                         if (IsA(e->arg, String))
6624                                 delay_string_append_char(message, str, v->val.str);
6625                         else
6626                         {
6627                                 snprintf(buf, 16, "%ld", v->val.ival);
6628                                 delay_string_append_char(message, str, buf);
6629                         }
6630                 }
6631         }
6632 }
6633
6634 static void
6635 _rewriteCreateSeqStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateSeqStmt *node)
6636 {
6637         delay_string_append_char(message, str, "CREATE ");
6638         if (node->sequence->istemp)
6639                 delay_string_append_char(message, str, "TEMP ");
6640         delay_string_append_char(message, str, "SEQUENCE ");
6641         _rewriteNode(BaseSelect, message, dblink, str, node->sequence);
6642
6643         _rewriteOptSeqList(BaseSelect, message, dblink, str, node->options);
6644 }
6645
6646 static void
6647 _rewriteAlterSeqStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterSeqStmt *node)
6648 {
6649         delay_string_append_char(message, str, "ALTER SEQUENCE ");
6650         _rewriteNode(BaseSelect, message, dblink, str, node->sequence);
6651         _rewriteOptSeqList(BaseSelect, message, dblink, str, node->options);
6652 }
6653
6654 static void
6655 _rewriteCreatePLangStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreatePLangStmt *node)
6656 {
6657         delay_string_append_char(message, str, "CREATE ");
6658         if (node->pltrusted == true)
6659                 delay_string_append_char(message, str, "TRUSTED ");
6660         delay_string_append_char(message, str, "LANGUAGE \"");
6661         delay_string_append_char(message, str, node->plname);
6662         delay_string_append_char(message, str, "\"");
6663
6664         if (node->plhandler != NIL)
6665         {
6666                 ListCell *lc;
6667                 char dot = 0;
6668
6669                 delay_string_append_char(message, str, " HANDLER ");
6670                 foreach (lc, node->plhandler)
6671                 {
6672                         Value *v = lfirst(lc);
6673
6674                         if (dot == 0)
6675                                 dot = 1;
6676                         else
6677                                 delay_string_append_char(message, str, ".");
6678
6679                         delay_string_append_char(message, str, "\"");
6680                         delay_string_append_char(message, str, v->val.str);
6681                         delay_string_append_char(message, str, "\"");
6682                 }
6683         }
6684
6685         if (node->plvalidator != NIL)
6686         {
6687                 ListCell *lc;
6688                 char dot = 0;
6689
6690                 delay_string_append_char(message, str, " VALIDATOR ");
6691                 foreach (lc, node->plvalidator)
6692                 {
6693                         Value *v = lfirst(lc);
6694
6695                         if (dot == 0)
6696                                 dot = 1;
6697                         else
6698                                 delay_string_append_char(message, str, ".");
6699
6700                         delay_string_append_char(message, str, "\"");
6701                         delay_string_append_char(message, str, v->val.str);
6702                         delay_string_append_char(message, str, "\"");
6703                 }
6704         }
6705 }
6706
6707 static void
6708 _rewriteDropPLangStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropPLangStmt *node)
6709 {
6710         delay_string_append_char(message, str, "DROP LANGUAGE \"");
6711         delay_string_append_char(message, str, node->plname);
6712         delay_string_append_char(message, str, "\"");
6713         if (node->behavior == DROP_CASCADE)
6714                 delay_string_append_char(message, str, " CASCADE");
6715 }
6716
6717 static void
6718 _rewriteCreateTableSpaceStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateTableSpaceStmt *node)
6719 {
6720         delay_string_append_char(message, str, "CREATE TABLESPACE \"");
6721         delay_string_append_char(message, str, node->tablespacename);
6722         delay_string_append_char(message, str, "\" ");
6723
6724         if (node->owner)
6725         {
6726                 delay_string_append_char(message, str, "OWNER \"");
6727                 delay_string_append_char(message, str, node->owner);
6728                 delay_string_append_char(message, str, "\" ");
6729         }
6730
6731         delay_string_append_char(message, str, "LOCATION '");
6732         delay_string_append_char(message, str, node->location);
6733         delay_string_append_char(message, str, "'");
6734 }
6735
6736 static void
6737 _rewriteDropTableSpaceStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropTableSpaceStmt *node)
6738 {
6739         delay_string_append_char(message, str, "DROP TABLESPACE \"");
6740         delay_string_append_char(message, str, node->tablespacename);
6741         delay_string_append_char(message, str, "\"");
6742 }
6743
6744 static void
6745 _rewriteFuncName(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *func_name)
6746 {
6747         ListCell *lc;
6748         Value *v;
6749         char dot = 0;
6750
6751         if (func_name == NULL)
6752                 return;
6753
6754         foreach (lc, func_name)
6755         {
6756                 v = (Value *) lfirst(lc);
6757
6758                 if (dot == 0)
6759                         dot = 1;
6760                 else
6761                         delay_string_append_char(message, str, ".");
6762
6763                 if (IsA(v, String))
6764                 {
6765                         //delay_string_append_char(message, str, "\"");
6766                         delay_string_append_char(message, str, v->val.str);
6767                         //delay_string_append_char(message, str, "\"");
6768                 }
6769                 else
6770                 {
6771                 }
6772         }
6773 }
6774
6775 static void
6776 _rewriteCreateTrigStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateTrigStmt *node)
6777 {
6778         int i, len;
6779
6780         if (node->isconstraint == TRUE)
6781                 delay_string_append_char(message, str, "CREATE CONSTRAINT TRIGGER \"");
6782         else
6783                 delay_string_append_char(message, str, "CREATE TRIGGER \"");
6784         delay_string_append_char(message, str, node->trigname);
6785         delay_string_append_char(message, str, "\" ");
6786
6787         if (node->before == TRUE)
6788                 delay_string_append_char(message, str, "BEFORE ");
6789         else
6790                 delay_string_append_char(message, str, "AFTER ");
6791
6792         len = strlen(node->actions);
6793         for (i = 0; i < len; i++)
6794         {
6795                 if (i)
6796                         delay_string_append_char(message, str, "OR ");
6797                 
6798                 if (node->actions[i] == 'i')
6799                         delay_string_append_char(message, str, "INSERT ");
6800                 else if (node->actions[i] == 'd')
6801                         delay_string_append_char(message, str, "DELETE ");
6802                 else
6803                         delay_string_append_char(message, str, "UPDATE ");
6804         }
6805
6806         delay_string_append_char(message, str, "ON ");
6807         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
6808
6809         if (node->constrrel)
6810         {
6811                 delay_string_append_char(message, str, " FROM ");
6812                 _rewriteNode(BaseSelect, message, dblink, str, node->constrrel);
6813         }
6814
6815         if (node->deferrable)
6816                 delay_string_append_char(message, str, " DEFERRABLE");
6817         if (node->initdeferred)
6818                 delay_string_append_char(message, str, " INITIALLY DEFERRED");
6819
6820         if (node->row == TRUE)
6821                 delay_string_append_char(message, str, " FOR EACH ROW ");
6822         else
6823                 delay_string_append_char(message, str, " FOR EACH STATEMENT ");
6824
6825         delay_string_append_char(message, str, "EXECUTE PROCEDURE ");
6826
6827         _rewriteFuncName(BaseSelect, message, dblink, str, node->funcname);
6828         delay_string_append_char(message, str, "(");
6829         _rewriteNode(BaseSelect, message, dblink, str, node->args);
6830         delay_string_append_char(message, str, ")");
6831 }
6832
6833 static void
6834 _rewriteDropPropertyStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropPropertyStmt *node)
6835 {
6836         switch (node->removeType)
6837         {
6838                 case OBJECT_TRIGGER:
6839                         delay_string_append_char(message, str, "DROP TRIGGER \"");
6840                         delay_string_append_char(message, str, node->property);
6841                         delay_string_append_char(message, str, "\" ON ");
6842                         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
6843                         if (node->behavior == DROP_CASCADE)
6844                                 delay_string_append_char(message, str, " CASCADE");
6845                         break;
6846
6847                 case OBJECT_RULE:
6848                         delay_string_append_char(message, str, "DROP RULE \"");
6849                         delay_string_append_char(message, str, node->property);
6850                         delay_string_append_char(message, str, "\" ON ");
6851                         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
6852                         if (node->behavior == DROP_CASCADE)
6853                                 delay_string_append_char(message, str, " CASCADE");
6854                         break;
6855
6856                 default:
6857                         break;
6858         }
6859 }
6860
6861 static void
6862 _rewriteDefinition(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *definition)
6863 {
6864         ListCell *lc;
6865         char comma = 0;
6866
6867         if (definition == NIL)
6868                 return;
6869
6870         delay_string_append_char(message, str, "(");
6871         foreach (lc, definition)
6872         {
6873                 DefElem *e = lfirst(lc);
6874
6875                 if (comma == 0)
6876                         comma = 1;
6877                 else
6878                         delay_string_append_char(message, str, ", ");
6879
6880                 delay_string_append_char(message, str, "\"");
6881                 delay_string_append_char(message, str, e->defname);
6882                 delay_string_append_char(message, str, "\"");
6883
6884                 if (e->arg)
6885                 {
6886                         delay_string_append_char(message, str, "=");
6887                         _rewriteNode(BaseSelect, message, dblink, str, e->arg);
6888                 }
6889         }
6890         delay_string_append_char(message, str, ")");
6891 }
6892
6893 static void
6894 _rewriteDefineStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DefineStmt *node)
6895 {
6896         ListCell *lc;
6897         char dot = 0;
6898
6899         switch (node->kind)
6900         {
6901                 case OBJECT_AGGREGATE:
6902                         delay_string_append_char(message, str, "CREATE AGGREGATE ");
6903                         _rewriteFuncName(BaseSelect, message, dblink, str, node->defnames);
6904                         delay_string_append_char(message, str, " ");
6905                         _rewriteDefinition(BaseSelect, message, dblink, str, node->definition);
6906                         break;
6907
6908                 case OBJECT_OPERATOR:
6909                         delay_string_append_char(message, str, "CREATE OPERATOR ");
6910
6911                         foreach (lc, node->defnames)
6912                         {
6913                                 Value *v = lfirst(lc);
6914
6915                                 if (dot == 0)
6916                                         dot = 1;
6917                                 else
6918                                         delay_string_append_char(message, str, ".");
6919
6920                                 delay_string_append_char(message, str, v->val.str);
6921                         }
6922
6923                         delay_string_append_char(message, str, " ");
6924                         _rewriteDefinition(BaseSelect, message, dblink, str, node->definition);
6925                         break;
6926
6927                 case OBJECT_TYPE:
6928                         delay_string_append_char(message, str, "CREATE TYPE");
6929                         _rewriteFuncName(BaseSelect, message, dblink, str, node->defnames);
6930                         delay_string_append_char(message, str, " ");
6931                         _rewriteDefinition(BaseSelect, message, dblink, str, node->definition);
6932                         break;
6933
6934                 case OBJECT_TSPARSER:
6935                         delay_string_append_char(message, str, "CREATE TEXT SEARCH PARSER ");
6936                         _rewriteIdList(BaseSelect, message, dblink, str, node->defnames);
6937                         _rewriteDefinition(BaseSelect, message, dblink, str, node->definition);
6938                         break;
6939
6940                 case OBJECT_TSDICTIONARY:
6941                         delay_string_append_char(message, str, "CREATE TEXT SEARCH DICTIONARY ");
6942                         _rewriteIdList(BaseSelect, message, dblink, str, node->defnames);
6943                         _rewriteDefinition(BaseSelect, message, dblink, str, node->definition);
6944                         break;
6945
6946                 case OBJECT_TSTEMPLATE:
6947                         delay_string_append_char(message, str, "CREATE TEXT SEARCH TEMPLATE ");
6948                         _rewriteIdList(BaseSelect, message, dblink, str, node->defnames);
6949                         _rewriteDefinition(BaseSelect, message, dblink, str, node->definition);
6950                         break;
6951
6952                 case OBJECT_TSCONFIGURATION:
6953                         delay_string_append_char(message, str, "CREATE TEXT SEARCH CONFIGURATION ");
6954                         _rewriteIdList(BaseSelect, message, dblink, str, node->defnames);
6955                         _rewriteDefinition(BaseSelect, message, dblink, str, node->definition);
6956                         break;
6957
6958                 default:
6959                         break;
6960         }
6961 }
6962
6963 static void
6964 _rewriteOperatorName(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *list)
6965 {
6966         char dot = 0;
6967         ListCell *lc;
6968
6969         foreach (lc, list)
6970         {
6971                 Value *v = lfirst(lc);
6972
6973                 if (dot == 0)
6974                         dot = 1;
6975                 else
6976                         delay_string_append_char(message, str, ".");
6977
6978                 delay_string_append_char(message, str, v->val.str);
6979         }
6980 }
6981
6982 static void
6983 _rewriteCreateOpClassItem(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateOpClassItem *node)
6984 {
6985         char buf[16];
6986
6987         switch (node->itemtype)
6988         {
6989                 case OPCLASS_ITEM_OPERATOR:
6990                         delay_string_append_char(message, str, "OPERATOR ");
6991                         snprintf(buf, 16, "%d", node->number);
6992                         delay_string_append_char(message, str, buf);
6993                         delay_string_append_char(message, str, " ");
6994                         _rewriteOperatorName(BaseSelect, message, dblink, str, node->name);
6995
6996                         if (node->args != NIL)
6997                         {
6998                                 delay_string_append_char(message, str, "(");
6999                                 _rewriteNode(BaseSelect, message, dblink, str, node->args);
7000                                 delay_string_append_char(message, str, ")");
7001                         }
7002                         if (node->recheck == TRUE)
7003                                 delay_string_append_char(message, str, " RECHECK");
7004                         break;
7005
7006                 case OPCLASS_ITEM_FUNCTION:
7007                         delay_string_append_char(message, str, "FUNCTION ");
7008                         snprintf(buf, 16, "%d", node->number);
7009                         delay_string_append_char(message, str, buf);
7010                         delay_string_append_char(message, str, " ");
7011                         _rewriteFuncName(BaseSelect, message, dblink, str, node->name);
7012                         delay_string_append_char(message, str, "(");
7013                         _rewriteNode(BaseSelect, message, dblink, str, node->args);
7014                         delay_string_append_char(message, str, ")");
7015                         break;
7016
7017                 case OPCLASS_ITEM_STORAGETYPE:
7018                         delay_string_append_char(message, str, "STORAGE ");
7019                         _rewriteNode(BaseSelect, message, dblink, str, node->storedtype);
7020                         break;
7021
7022                 default:
7023                         break;
7024         }
7025
7026 }
7027
7028 static void
7029 _rewriteCreateOpClassStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateOpClassStmt *node)
7030 {
7031         delay_string_append_char(message, str, "CREATE OPERATOR CLASS ");
7032         _rewriteFuncName(BaseSelect, message, dblink, str, node->opclassname);
7033
7034         if (node->isDefault == TRUE)
7035                 delay_string_append_char(message, str, " DEFAULT");
7036
7037         delay_string_append_char(message, str, " FOR TYPE ");
7038         _rewriteNode(BaseSelect, message, dblink, str, node->datatype);
7039         delay_string_append_char(message, str, " USING ");
7040         delay_string_append_char(message, str, node->amname);
7041         delay_string_append_char(message, str, " AS ");
7042         _rewriteNode(BaseSelect, message, dblink, str, node->items);
7043 }
7044
7045 static void
7046 _rewriteRemoveOpClassStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RemoveOpClassStmt *node)
7047 {
7048         delay_string_append_char(message, str, "DROP OPERATOR CLASS ");
7049         _rewriteFuncName(BaseSelect, message, dblink, str, node->opclassname);
7050         delay_string_append_char(message, str, " USING ");
7051         delay_string_append_char(message, str, node->amname);
7052         if (node->behavior == DROP_CASCADE)
7053                 delay_string_append_char(message, str, " CASCADE");
7054 }
7055
7056 static void
7057 _rewriteDropStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropStmt *node)
7058 {
7059         ListCell *lc;
7060         char comma = 0;
7061
7062         delay_string_append_char(message, str, "DROP ");
7063         switch (node->removeType)
7064         {
7065                 case OBJECT_TABLE:
7066                         delay_string_append_char(message, str, "TABLE ");
7067                         break;
7068
7069                 case OBJECT_SEQUENCE:
7070                         delay_string_append_char(message, str, "SEQUENCE ");
7071                         break;
7072
7073                 case OBJECT_VIEW:
7074                         delay_string_append_char(message, str, "VIEW ");
7075                         break;
7076
7077                 case OBJECT_INDEX:
7078                         delay_string_append_char(message, str, "INDEX ");
7079                         break;
7080
7081                 case OBJECT_TYPE:
7082                         delay_string_append_char(message, str, "TYPE ");
7083                         break;
7084
7085                 case OBJECT_DOMAIN:
7086                         delay_string_append_char(message, str, "DOMAIN ");
7087                         break;
7088
7089                 case OBJECT_CONVERSION:
7090                         delay_string_append_char(message, str, "CONVERSION ");
7091                         break;
7092
7093                 case OBJECT_SCHEMA:
7094                         delay_string_append_char(message, str, "SCHEMA ");
7095                         break;
7096
7097                 default:
7098                         break;
7099         }
7100
7101         foreach (lc, node->objects)
7102         {
7103                 if (comma == 0)
7104                         comma = 1;
7105                 else
7106                         delay_string_append_char(message, str, ", ");
7107                 _rewriteFuncName(BaseSelect, message, dblink, str, lfirst(lc));
7108         }
7109
7110         if (node->behavior == DROP_CASCADE)
7111                 delay_string_append_char(message, str, " CASCADE");
7112 }
7113
7114 static void
7115 _rewriteFetchStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FetchStmt *node)
7116 {
7117         char buf[16];
7118
7119         snprintf(buf, 16, "%ld", node->howMany);
7120
7121         if (node->ismove == TRUE)
7122                 delay_string_append_char(message, str, "MOVE ");
7123         else
7124                 delay_string_append_char(message, str, "FETCH ");
7125
7126         switch (node->direction)
7127         {
7128                 case FETCH_FORWARD:
7129                         delay_string_append_char(message, str, "FORWARD ");
7130                         if (node->howMany == FETCH_ALL)
7131                                 delay_string_append_char(message, str, "ALL ");
7132                         else
7133                         {
7134                                 delay_string_append_char(message, str, buf);
7135                                 delay_string_append_char(message, str, " ");
7136                         }
7137                         break;
7138
7139                 case FETCH_BACKWARD:
7140                         delay_string_append_char(message, str, "BACKWARD ");
7141                         if (node->howMany == FETCH_ALL)
7142                                 delay_string_append_char(message, str, "ALL ");
7143                         else
7144                         {
7145                                 delay_string_append_char(message, str, buf);
7146                                 delay_string_append_char(message, str, " ");
7147                         }
7148                         break;
7149
7150                 case FETCH_ABSOLUTE:
7151                         if (node->howMany == 1)
7152                                 delay_string_append_char(message, str, "FIRST ");
7153                         else if (node->howMany == -1)
7154                                 delay_string_append_char(message, str, "LAST ");
7155                         else
7156                         {
7157                                 delay_string_append_char(message, str, "ABSOLUTE ");
7158                                 delay_string_append_char(message, str, buf);
7159                                 delay_string_append_char(message, str, " ");
7160                         }
7161                         break;
7162
7163                 case FETCH_RELATIVE:
7164                         delay_string_append_char(message, str, "RELATIVE ");
7165                         delay_string_append_char(message, str, buf);
7166                         delay_string_append_char(message, str, " ");
7167                         break;
7168         }
7169
7170         delay_string_append_char(message, str, "IN \"");
7171         delay_string_append_char(message, str, node->portalname);
7172         delay_string_append_char(message, str, "\"");
7173 }
7174
7175 static void
7176 _rewritePrivilegeList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *list)
7177 {
7178         ListCell *lc;
7179         char comma = 0;
7180
7181         if (list == NIL)
7182                 delay_string_append_char(message, str, "ALL");
7183         else
7184         {
7185                 foreach (lc, list)
7186                 {
7187                         Value *v = lfirst(lc);
7188
7189                         if (comma == 0)
7190                                 comma = 1;
7191                         else
7192                                 delay_string_append_char(message, str, ", ");
7193
7194                         delay_string_append_char(message, str, v->val.str);
7195                 }
7196         }
7197 }
7198
7199 static void
7200 _rewriteFunctionParameter(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FunctionParameter *node)
7201 {
7202         switch (node->mode)
7203         {
7204                 case FUNC_PARAM_OUT:
7205                         delay_string_append_char(message, str, "OUT ");
7206                         break;
7207
7208                 case FUNC_PARAM_INOUT:
7209                         delay_string_append_char(message, str, "INOUT ");
7210                         break;
7211
7212                 default:
7213                         break;
7214         }
7215
7216         /* function name */
7217         if (node->name)
7218         {
7219                 delay_string_append_char(message, str, "\"");
7220                 delay_string_append_char(message, str, node->name);
7221                 delay_string_append_char(message, str, "\" ");
7222         }
7223
7224         _rewriteNode(BaseSelect, message, dblink, str, node->argType);
7225 }
7226
7227 static void
7228 _rewriteFuncWithArgs(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, FuncWithArgs *node)
7229 {
7230         _rewriteFuncName(BaseSelect, message, dblink, str, node->funcname);
7231         delay_string_append_char(message, str, "(");
7232         _rewriteNode(BaseSelect, message, dblink, str, node->funcargs);
7233         delay_string_append_char(message, str, ")");
7234 }
7235
7236 static void
7237 _rewritePrivTarget(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, PrivTarget *node)
7238 {
7239         switch (node->objtype)
7240         {
7241                 case ACL_OBJECT_RELATION:
7242                         _rewriteNode(BaseSelect, message, dblink, str, node->objs);
7243                         break;
7244
7245                 case ACL_OBJECT_SEQUENCE:
7246                         delay_string_append_char(message, str, "SEQUENCE ");
7247                         _rewriteNode(BaseSelect, message, dblink, str, node->objs);
7248                         break;
7249
7250                 case ACL_OBJECT_FUNCTION:
7251                         delay_string_append_char(message, str, "FUNCTION ");
7252                         _rewriteNode(BaseSelect, message, dblink, str, node->objs);
7253                         break;
7254
7255                 case ACL_OBJECT_DATABASE:
7256                         delay_string_append_char(message, str, "DATABASE ");
7257                         _rewriteIdList(BaseSelect, message, dblink, str, node->objs);
7258                         break;
7259
7260                 case ACL_OBJECT_LANGUAGE:
7261                         delay_string_append_char(message, str, "LANGUAGE ");
7262                         _rewriteIdList(BaseSelect, message, dblink, str, node->objs);
7263                         break;
7264
7265                 case ACL_OBJECT_NAMESPACE:
7266                         delay_string_append_char(message, str, "SCHEMA ");
7267                         _rewriteIdList(BaseSelect, message, dblink, str, node->objs);
7268                         break;
7269
7270                 case ACL_OBJECT_TABLESPACE:
7271                         delay_string_append_char(message, str, "TABLESPACE ");
7272                         _rewriteIdList(BaseSelect, message, dblink, str, node->objs);
7273                         break;
7274         }
7275 }
7276
7277 static void
7278 _rewritePrivGrantee(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, PrivGrantee *node)
7279 {
7280         if (node->rolname == NULL)
7281                 delay_string_append_char(message, str, "PUBLIC");
7282         else
7283         {
7284                 delay_string_append_char(message, str, "\"");
7285                 delay_string_append_char(message, str, node->rolname);
7286                 delay_string_append_char(message, str, "\"");
7287         }
7288 }
7289
7290 static void
7291 _rewriteGrantStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, GrantStmt *node)
7292 {
7293         PrivTarget *n;
7294         
7295         if (node->is_grant == true)
7296                 delay_string_append_char(message, str, "GRANT ");
7297         else
7298         {
7299                 delay_string_append_char(message, str, "REVOKE ");
7300                 if (node->grant_option == true)
7301                         delay_string_append_char(message, str, "GRANT OPTION FOR ");
7302         }
7303
7304         _rewritePrivilegeList(BaseSelect, message, dblink, str, node->privileges);
7305
7306         delay_string_append_char(message, str, " ON ");
7307
7308         n = makeNode(PrivTarget);
7309         n->objtype = node->objtype;
7310         n->objs = node->objects;
7311         _rewriteNode(BaseSelect, message, dblink, str, n);
7312         pfree(n);
7313
7314         if (node->is_grant == true)
7315                 delay_string_append_char(message, str, " TO ");
7316         else
7317                 delay_string_append_char(message, str, " FROM ");
7318         _rewriteNode(BaseSelect, message, dblink, str, node->grantees);
7319
7320         if (node->is_grant == true && node->grant_option == TRUE)
7321                 delay_string_append_char(message, str, " WITH GRANT OPTION");
7322
7323         if (node->behavior == DROP_CASCADE)
7324                 delay_string_append_char(message, str, " CASCADE");
7325
7326 }
7327
7328 static void
7329 _rewriteGrantRoleStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, GrantRoleStmt *node)
7330 {
7331         if (node->is_grant == true)
7332                 delay_string_append_char(message, str, "GRANT ");
7333         else
7334         {
7335                 delay_string_append_char(message, str, "REVOKE ");
7336                 if (node->admin_opt == true)
7337                         delay_string_append_char(message, str, "ADMIN OPTION FOR ");
7338         }
7339
7340         _rewriteIdList(BaseSelect, message, dblink, str, node->granted_roles);
7341
7342         delay_string_append_char(message, str, node->is_grant == true ? " TO " : " FROM ");
7343
7344         _rewriteIdList(BaseSelect, message, dblink, str, node->grantee_roles);
7345
7346         if (node->admin_opt == true && node->is_grant == true)
7347                 delay_string_append_char(message, str, "  WITH ADMIN OPTION");
7348
7349         if (node->grantor != NULL)
7350         {
7351                 delay_string_append_char(message, str, " GRANTED BY \"");
7352                 delay_string_append_char(message, str, node->grantor);
7353                 delay_string_append_char(message, str, "\"");
7354         }
7355
7356         if (node->behavior == DROP_CASCADE)
7357                 delay_string_append_char(message, str, " CASCADE");
7358 }
7359
7360 static void
7361 _rewriteFuncOptList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *list)
7362 {
7363         ListCell *lc;
7364
7365         foreach (lc, list)
7366         {
7367                 DefElem *e = lfirst(lc);
7368                 Value *v = (Value *) e->arg;
7369
7370                 if (strcmp(e->defname, "strict") == 0)
7371                 {
7372                         if (v->val.ival == TRUE)
7373                                 delay_string_append_char(message, str, " STRICT");
7374                         else
7375                                 delay_string_append_char(message, str, " CALLED ON NULL INPUT");
7376                 }
7377                 else if (strcmp(e->defname, "volatility") == 0)
7378                 {
7379                         char *s = v->val.str;
7380                         if (strcmp(s, "immutable") == 0)
7381                                 delay_string_append_char(message, str, " IMMUTABLE");
7382                         else if (strcmp(s, "stable") == 0)
7383                                 delay_string_append_char(message, str, " STABLE");
7384                         else if (strcmp(s, "volatile") == 0)
7385                                 delay_string_append_char(message, str, " VOLATILE");
7386                 }
7387                 else if (strcmp(e->defname, "security") == 0)
7388                 {
7389                         if (v->val.ival == TRUE)
7390                                 delay_string_append_char(message, str, " SECURITY DEFINER");
7391                         else
7392                                 delay_string_append_char(message, str, " SECURITY INVOKER");
7393                 }
7394                 else if (strcmp(e->defname, "as") == 0)
7395                 {
7396                         delay_string_append_char(message, str, " AS ");
7397                         _rewriteNode(BaseSelect, message, dblink, str, e->arg);
7398                 }
7399                 else if (strcmp(e->defname, "language") == 0)
7400                 {
7401                         delay_string_append_char(message, str, " LANGUAGE '");
7402                         delay_string_append_char(message, str, v->val.str);
7403                         delay_string_append_char(message, str, "'");
7404                 }
7405         }
7406 }
7407
7408 static void
7409 _rewriteCreateFunctionStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateFunctionStmt *node)
7410 {
7411         delay_string_append_char(message, str, "CREATE ");
7412         if (node->replace == true)
7413                 delay_string_append_char(message, str, "OR REPLACE ");
7414         delay_string_append_char(message, str, "FUNCTION ");
7415
7416         _rewriteFuncName(BaseSelect, message, dblink, str, node->funcname);
7417
7418         delay_string_append_char(message, str, " (");
7419         _rewriteNode(BaseSelect, message, dblink, str, node->parameters);
7420         delay_string_append_char(message, str, ")");
7421
7422         if (node->returnType)
7423         {
7424                 delay_string_append_char(message, str, " RETURNS ");
7425                 _rewriteNode(BaseSelect, message, dblink, str, node->returnType);
7426         }
7427
7428         _rewriteFuncOptList(BaseSelect, message, dblink, str, node->options);
7429
7430         if (node->withClause)
7431         {
7432                 delay_string_append_char(message, str, " WITH ");
7433                 _rewriteDefinition(BaseSelect, message, dblink, str, node->withClause);
7434         }
7435 }
7436
7437 static void
7438 _rewriteAlterFunctionStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterFunctionStmt *node)
7439 {
7440         delay_string_append_char(message, str, "ALTER FUNCTION ");
7441         _rewriteNode(BaseSelect, message, dblink, str, node->func);
7442         _rewriteFuncOptList(BaseSelect, message, dblink, str, node->actions);
7443 }
7444
7445 static void
7446 _rewriteRemoveFuncStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RemoveFuncStmt *node)
7447 {
7448         switch (node->kind)
7449         {
7450                 case OBJECT_FUNCTION:
7451                         delay_string_append_char(message, str, "DROP FUNCTION ");
7452                         break;
7453
7454                 case OBJECT_AGGREGATE:
7455                         delay_string_append_char(message, str, "DROP AGGREGATE ");
7456                         break;
7457
7458                 case OBJECT_OPERATOR:
7459                         delay_string_append_char(message, str, "DROP OPERATOR CLASS ");
7460                         break;
7461
7462                 default:
7463                         break;
7464         }
7465
7466         if (node->missing_ok)
7467                 delay_string_append_char(message, str, "IF EXISTS ");
7468
7469         _rewriteFuncName(BaseSelect, message, dblink, str, node->name);
7470
7471         delay_string_append_char(message, str, " (");
7472         _rewriteNode(BaseSelect, message, dblink, str, node->args);
7473         delay_string_append_char(message, str, ")");
7474
7475         if (node->behavior == DROP_CASCADE)
7476                 delay_string_append_char(message, str, " CASCADE");
7477 }
7478
7479 static void
7480 _rewriteCreateCastStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateCastStmt *node)
7481 {
7482         delay_string_append_char(message, str, "CREATE CAST (");
7483         _rewriteNode(BaseSelect, message, dblink, str, node->sourcetype);
7484         delay_string_append_char(message, str, " AS ");
7485         _rewriteNode(BaseSelect, message, dblink, str, node->targettype);
7486         delay_string_append_char(message, str, ") WITH FUNCTION ");
7487         _rewriteNode(BaseSelect, message, dblink, str, node->func);
7488
7489         switch (node->context)
7490         {
7491                 case COERCION_IMPLICIT:
7492                         delay_string_append_char(message, str, " AS IMPLICIT");
7493                         break;
7494
7495                 case COERCION_ASSIGNMENT:
7496                         delay_string_append_char(message, str, " AS ASSIGNMENT");
7497                         break;
7498
7499                 default:
7500                         break;
7501         }
7502 }
7503
7504 static void
7505 _rewriteDropCastStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropCastStmt *node)
7506 {
7507         delay_string_append_char(message, str, "DROP CAST (");
7508         _rewriteNode(BaseSelect, message, dblink, str, node->sourcetype);
7509         delay_string_append_char(message, str, " AS ");
7510         _rewriteNode(BaseSelect, message, dblink, str, node->targettype);
7511         delay_string_append_char(message, str, ")");
7512
7513         if (node->behavior == DROP_CASCADE)
7514                 delay_string_append_char(message, str, " CASCADE");
7515 }
7516
7517 static void
7518 _rewriteReindexStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ReindexStmt *node)
7519 {
7520         delay_string_append_char(message, str, "REINDEX ");
7521
7522         switch (node->kind)
7523         {
7524                 case OBJECT_DATABASE:
7525                         if (node->do_system == true && node->do_user == false)
7526                                 delay_string_append_char(message, str, "SYSTEM ");
7527                         else
7528                                 delay_string_append_char(message, str, "DATABASE ");
7529                         break;
7530
7531                 case OBJECT_INDEX:
7532                         delay_string_append_char(message, str, "INDEX ");
7533                         break;
7534
7535                 case OBJECT_TABLE:
7536                         delay_string_append_char(message, str, "TABLE ");
7537                         break;
7538
7539                 default:
7540                         break;
7541         }
7542
7543         if (node->relation)
7544                 _rewriteNode(BaseSelect, message, dblink, str, node->relation);
7545
7546         if (node->name)
7547         {
7548                 delay_string_append_char(message, str, "\"");
7549                 delay_string_append_char(message, str, (char *) node->name);
7550                 delay_string_append_char(message, str, "\"");
7551         }
7552 }
7553
7554 static void
7555 _rewriteAlterObjectSchemaStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterObjectSchemaStmt *node)
7556 {
7557         delay_string_append_char(message, str, "ALTER ");
7558
7559         switch (node->objectType)
7560         {
7561                 case OBJECT_AGGREGATE:
7562                         delay_string_append_char(message, str, "AGGREGATE ");
7563                         _rewriteFuncName(BaseSelect, message, dblink, str, node->object);
7564                         delay_string_append_char(message, str, "(");
7565                         if (lfirst(list_head(node->objarg)) == NULL)
7566                                 delay_string_append_char(message, str, "*");
7567                         else
7568                                 _rewriteNode(BaseSelect, message, dblink, str, lfirst(list_head(node->objarg)));
7569                         delay_string_append_char(message, str, ") SET SCHAME \"");
7570                         delay_string_append_char(message, str, node->newschema);
7571                         delay_string_append_char(message, str, "\"");
7572                         break;
7573
7574                 case OBJECT_DOMAIN:
7575                         delay_string_append_char(message, str, "DOMAIN ");
7576                         _rewriteFuncName(BaseSelect, message, dblink, str, node->object);
7577                         delay_string_append_char(message, str, " SET SCHEMA \"");
7578                         delay_string_append_char(message, str, node->newschema);
7579                         delay_string_append_char(message, str, "\"");
7580                         break;
7581
7582                 case OBJECT_FUNCTION:
7583                         delay_string_append_char(message, str, "FUNCTION ");
7584                         _rewriteFuncName(BaseSelect, message, dblink, str, node->object);
7585                         delay_string_append_char(message, str, "(");
7586                         _rewriteNode(BaseSelect, message, dblink, str, node->objarg);
7587                         delay_string_append_char(message, str, ") SET SCHEMA \"");
7588                         delay_string_append_char(message, str, node->newschema);
7589                         delay_string_append_char(message, str, "\"");
7590                         break;
7591
7592                 case OBJECT_SEQUENCE:
7593                         delay_string_append_char(message, str, "SEQUENCE ");
7594                         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
7595                         delay_string_append_char(message, str, " SET SCHEMA \"");
7596                         delay_string_append_char(message, str, node->newschema);
7597                         delay_string_append_char(message, str, "\"");
7598                         break;
7599
7600                 case OBJECT_TABLE:
7601                         delay_string_append_char(message, str, "TABLE ");
7602                         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
7603                         delay_string_append_char(message, str, " SET SCHEMA \"");
7604                         delay_string_append_char(message, str, node->newschema);
7605                         delay_string_append_char(message, str, "\"");
7606                         break;
7607
7608                 case OBJECT_TYPE:
7609                         delay_string_append_char(message, str, "TYPE ");
7610                         _rewriteFuncName(BaseSelect, message, dblink, str, node->object);
7611                         delay_string_append_char(message, str, " SET SCHEMA \"");
7612                         delay_string_append_char(message, str, node->newschema);
7613                         delay_string_append_char(message, str, "\"");
7614                         break;
7615
7616                 default:
7617                         break;
7618         }
7619 }
7620
7621 static void
7622 _rewriteAlterOwnerStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterOwnerStmt *node)
7623 {
7624         delay_string_append_char(message, str, "ALTER ");
7625
7626         switch (node->objectType)
7627         {
7628                 case OBJECT_AGGREGATE:
7629                         delay_string_append_char(message, str, "AGGREGATE ");
7630                         _rewriteFuncName(BaseSelect, message, dblink, str, node->object);
7631                         delay_string_append_char(message, str, "(");
7632                         if (lfirst(list_head(node->objarg)) == NULL)
7633                                 delay_string_append_char(message, str, "*");
7634                         else
7635                                 _rewriteNode(BaseSelect, message, dblink, str, lfirst(list_head(node->objarg)));
7636                         delay_string_append_char(message, str, ") OWNER TO \"");
7637                         delay_string_append_char(message, str, node->newowner);
7638                         delay_string_append_char(message, str, "\"");
7639                         break;
7640
7641                 case OBJECT_CONVERSION:
7642                         delay_string_append_char(message, str, "CONVERSION ");
7643                         _rewriteFuncName(BaseSelect, message, dblink, str, node->object);
7644                         delay_string_append_char(message, str, " OWNER TO \"");
7645                         delay_string_append_char(message, str, node->newowner);
7646                         delay_string_append_char(message, str, "\"");
7647                         break;
7648
7649                 case OBJECT_DATABASE:
7650                         delay_string_append_char(message, str, "DATABASE \"");
7651                         _rewriteIdList(BaseSelect, message, dblink, str, node->object);
7652                         delay_string_append_char(message, str, "\" OWNER TO \"");
7653                         delay_string_append_char(message, str, node->newowner);
7654                         delay_string_append_char(message, str, "\"");
7655                         break;
7656
7657                 case OBJECT_DOMAIN:
7658                         delay_string_append_char(message, str, "DOMAIN ");
7659                         _rewriteFuncName(BaseSelect, message, dblink, str, node->object);
7660                         delay_string_append_char(message, str, " OWNER TO \"");
7661                         delay_string_append_char(message, str, node->newowner);
7662                         delay_string_append_char(message, str, "\"");
7663                         break;
7664
7665                 case OBJECT_FUNCTION:
7666                         delay_string_append_char(message, str, "FUNCTION ");
7667                         _rewriteFuncName(BaseSelect, message, dblink, str, node->object);
7668                         delay_string_append_char(message, str, "(");
7669                         _rewriteNode(BaseSelect, message, dblink, str, node->objarg);
7670                         delay_string_append_char(message, str, ") OWNER TO \"");
7671                         delay_string_append_char(message, str, node->newowner);
7672                         delay_string_append_char(message, str, "\"");
7673                         break;
7674
7675                 case OBJECT_OPERATOR:
7676                         delay_string_append_char(message, str, "OPERATOR ");
7677                         _rewriteOperatorName(BaseSelect, message, dblink, str, node->object);
7678                         delay_string_append_char(message, str, "(");
7679                         _rewriteOperatorArgTypes(BaseSelect, message, dblink, str, node->objarg);
7680                         delay_string_append_char(message, str, ") OWNER TO \"");
7681                         delay_string_append_char(message, str, node->newowner);
7682                         delay_string_append_char(message, str, "\"");
7683                         break;
7684
7685                 case OBJECT_OPCLASS:
7686                         delay_string_append_char(message, str, "OPERATOR CLASS ");
7687                         _rewriteFuncName(BaseSelect, message, dblink, str, node->object);
7688                         delay_string_append_char(message, str, " USING ");
7689                         delay_string_append_char(message, str, node->addname);
7690                         delay_string_append_char(message, str, " OWNER TO \"");
7691                         delay_string_append_char(message, str, node->newowner);
7692                         delay_string_append_char(message, str, "\"");
7693                         break;
7694
7695                 case OBJECT_SCHEMA:
7696                         delay_string_append_char(message, str, "SCHEMA \"");
7697                         delay_string_append_char(message, str, linitial(node->object));
7698                         delay_string_append_char(message, str, "\" OWNER TO \"");
7699                         delay_string_append_char(message, str, node->newowner);
7700                         delay_string_append_char(message, str, "\"");
7701                         break;
7702
7703                 case OBJECT_TYPE:
7704                         delay_string_append_char(message, str, "TYPE ");
7705                         _rewriteFuncName(BaseSelect, message, dblink, str, node->object);
7706                         delay_string_append_char(message, str, " OWNER TO \"");
7707                         delay_string_append_char(message, str, node->newowner);
7708                         delay_string_append_char(message, str, "\"");
7709                         break;
7710
7711                 case OBJECT_TABLESPACE:
7712                         delay_string_append_char(message, str, "TABLESPACE \"");
7713                         delay_string_append_char(message, str, linitial(node->object));
7714                         delay_string_append_char(message, str, "\" OWNER TO \"");
7715                         delay_string_append_char(message, str, node->newowner);
7716                         delay_string_append_char(message, str, "\"");
7717                         break;
7718
7719                 default:
7720                         break;
7721         }
7722 }
7723
7724 static void
7725 _rewriteRuleStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RuleStmt *node)
7726 {
7727         delay_string_append_char(message, str, "CREATE ");
7728         if (node->replace)
7729                 delay_string_append_char(message, str, "OR REPLACE ");
7730         delay_string_append_char(message, str, "RULE \"");
7731         delay_string_append_char(message, str, node->rulename);
7732         delay_string_append_char(message, str, "\" AS ON ");
7733
7734         switch (node->event)
7735         {
7736                 case CMD_SELECT:
7737                         delay_string_append_char(message, str, "SELECT");
7738                         break;
7739
7740                 case CMD_UPDATE:
7741                         delay_string_append_char(message, str, "UPDATE");
7742                         break;
7743
7744                 case CMD_DELETE:
7745                         delay_string_append_char(message, str, "DELETE");
7746                         break;
7747
7748                 case CMD_INSERT:
7749                         delay_string_append_char(message, str, "INSERT");
7750                         break;
7751
7752                 default:
7753                         break;
7754         }
7755
7756         delay_string_append_char(message, str, " TO ");
7757         _rewriteNode(BaseSelect, message, dblink, str, node->relation);
7758
7759         if (node->whereClause)
7760         {
7761                 delay_string_append_char(message, str, " WHERE ");
7762                 _rewriteNode(BaseSelect, message, dblink, str, node->whereClause);
7763         }
7764
7765         delay_string_append_char(message, str, " DO ");
7766
7767         if (node->instead)
7768                 delay_string_append_char(message, str, "INSTEAD ");
7769
7770         if (node->actions == NIL)
7771                 delay_string_append_char(message, str, "NOTHING");
7772         else if (list_length(node->actions) == 1)
7773                 _rewriteNode(BaseSelect, message, dblink, str, linitial(node->actions));
7774         else
7775         {
7776                 ListCell *lc;
7777                 char semi = 0;
7778
7779                 delay_string_append_char(message, str, "(");
7780
7781                 foreach (lc, node->actions)
7782                 {
7783                         if (semi == 0)
7784                                 semi = 1;
7785                         else
7786                                 delay_string_append_char(message, str, ";");
7787
7788                         _rewriteNode(BaseSelect, message, dblink, str, lfirst(lc));
7789                 }
7790
7791                 delay_string_append_char(message, str, ")");
7792         }
7793 }
7794
7795 static void
7796 _rewriteViewStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ViewStmt *node)
7797 {
7798         if (node->replace)
7799                 delay_string_append_char(message, str, "CREATE OR REPLACE ");
7800         else
7801                 delay_string_append_char(message, str, "CREATE ");
7802
7803         if (node->view->istemp == TRUE)
7804                 delay_string_append_char(message, str, "TEMP ");
7805
7806         delay_string_append_char(message, str, "VIEW ");
7807         _rewriteNode(BaseSelect, message, dblink, str, node->view);
7808
7809         if (node->aliases)
7810         {
7811                 delay_string_append_char(message, str, "(");
7812                 _rewriteIdList(BaseSelect, message, dblink, str, node->aliases);
7813                 delay_string_append_char(message, str, ")");
7814         }
7815
7816         delay_string_append_char(message, str, " AS");
7817         _rewriteNode(BaseSelect, message, dblink, str, node->query);
7818 }
7819
7820 static void
7821 _rewriteCreatedbOptList(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *options)
7822 {
7823         ListCell *lc;
7824
7825         foreach (lc, options)
7826         {
7827                 DefElem *e = lfirst(lc);
7828                 Value *v = (Value *) e->arg;
7829                 int sconst = false;
7830
7831                 /* keyword */
7832                 if (strcmp(e->defname, "template") == 0)
7833                         delay_string_append_char(message, str, " TEMPLATE ");
7834                 else if (strcmp(e->defname, "location") == 0)
7835                 {
7836                         delay_string_append_char(message, str, " LOCATION ");
7837                         sconst = true;
7838                 }
7839                 else if (strcmp(e->defname, "tablespace") == 0)
7840                         delay_string_append_char(message, str, " TABLESPACE ");
7841                 else if (strcmp(e->defname, "encoding") == 0)
7842                 {
7843                         delay_string_append_char(message, str, " ENCODING ");
7844                         sconst = true;
7845                 }
7846                 else if (strcmp(e->defname, "owner") == 0)
7847                         delay_string_append_char(message, str, " OWNER ");
7848                 else if (strcmp(e->defname, "connectionlimit") == 0)
7849                         delay_string_append_char(message, str, " CONNECTION LIMIT ");
7850
7851                 /* value */
7852                 if (v == NULL)
7853                         delay_string_append_char(message, str, "DEFAULT");
7854                 else if (IsA((Node *)v, String))
7855                 {
7856                         delay_string_append_char(message, str, sconst ? "'" : "'");
7857                         delay_string_append_char(message, str, v->val.str);
7858                         delay_string_append_char(message, str, sconst ? "'" : "'");
7859                 }
7860                 else
7861                 {
7862                         char buf[16];
7863                         snprintf(buf, 16, "%ld", v->val.ival);
7864                         delay_string_append_char(message, str, buf);
7865                 }
7866         }
7867 }
7868
7869 static void
7870 _rewriteCreatedbStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreatedbStmt *node)
7871 {
7872         delay_string_append_char(message, str, "CREATE DATABASE \"");
7873         delay_string_append_char(message, str, node->dbname);
7874         delay_string_append_char(message, str, "\"");
7875
7876         _rewriteCreatedbOptList(BaseSelect, message, dblink, str, node->options);
7877 }
7878
7879 static void
7880 _rewriteAlterDatabaseStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterDatabaseStmt *node)
7881 {
7882         delay_string_append_char(message, str, "ALTER DATABASE \"");
7883         delay_string_append_char(message, str, node->dbname);
7884         delay_string_append_char(message, str, "\" ");
7885
7886         _rewriteCreatedbOptList(BaseSelect, message, dblink, str, node->options);
7887 }
7888
7889 static void
7890 _rewriteAlterDatabaseSetStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterDatabaseSetStmt *node)
7891 {
7892         delay_string_append_char(message, str, "ALTER DATABASE \"");
7893         delay_string_append_char(message, str, node->dbname);
7894         delay_string_append_char(message, str, "\" ");
7895
7896         _rewriteNode(BaseSelect, message, dblink, str, node->setstmt);
7897 }
7898
7899 static void
7900 _rewriteDropdbStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, DropdbStmt *node)
7901 {
7902         delay_string_append_char(message, str, "DROP DATABASE \"");
7903         delay_string_append_char(message, str, node->dbname);
7904         delay_string_append_char(message, str, "\"");
7905 }
7906
7907 static void
7908 _rewriteCreateDomainStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateDomainStmt *node)
7909 {
7910         ListCell *lc;
7911
7912         delay_string_append_char(message, str, "CREATE DOMAIN ");
7913         _rewriteFuncName(BaseSelect, message, dblink, str, node->domainname);
7914         delay_string_append_char(message, str, " ");
7915         _rewriteNode(BaseSelect, message, dblink, str, node->typename);
7916
7917
7918         foreach (lc, node->constraints)
7919         {
7920                 delay_string_append_char(message, str, " ");
7921                 _rewriteNode(BaseSelect, message, dblink, str, lfirst(lc));
7922         }
7923 }
7924
7925 static void
7926 _rewriteAlterDomainStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, AlterDomainStmt *node)
7927 {
7928         delay_string_append_char(message, str, "ALTER DOMAIN ");
7929         _rewriteFuncName(BaseSelect, message, dblink, str, node->typename);
7930
7931         switch (node->subtype)
7932         {
7933                 case 'T':
7934                         if (node->def)
7935                         {
7936                                 delay_string_append_char(message, str, " SET DEFAULT ");
7937                                 _rewriteNode(BaseSelect, message, dblink, str, node->def);
7938                         }
7939                         else
7940                                 delay_string_append_char(message, str, " DROP DEFAULT");
7941                         break;
7942
7943                 case 'N':
7944                         delay_string_append_char(message, str, " DROP NOT NULL");
7945                         break;
7946
7947                 case 'O':
7948                         delay_string_append_char(message, str, " SET NOT NULL");
7949                         break;
7950
7951                 case 'C':
7952                         delay_string_append_char(message, str, " ADD ");
7953                         _rewriteNode(BaseSelect, message, dblink, str, node->def);
7954                         break;
7955
7956                 case 'X':
7957                         delay_string_append_char(message, str, " DROP CONSTRAINT \"");
7958                         delay_string_append_char(message, str, node->name);
7959                         delay_string_append_char(message, str, "\"");
7960                         if (node->behavior == DROP_CASCADE)
7961                                 delay_string_append_char(message, str, " CASCADE");
7962                         break;
7963         }
7964 }
7965
7966 static void
7967 _rewriteCreateConversionStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CreateConversionStmt *node)
7968 {
7969         delay_string_append_char(message, str, "CREATE ");
7970
7971         if (node->def == TRUE)
7972                 delay_string_append_char(message, str, "DEFAULT ");
7973
7974         delay_string_append_char(message, str, "CONVERSION ");
7975
7976         _rewriteFuncName(BaseSelect, message, dblink, str, node->conversion_name);
7977
7978         delay_string_append_char(message, str, " FOR '");
7979         delay_string_append_char(message, str, node->for_encoding_name);
7980         delay_string_append_char(message, str, "' TO '");
7981         delay_string_append_char(message, str, node->to_encoding_name);
7982         delay_string_append_char(message, str, " FROM ");
7983         _rewriteFuncName(BaseSelect, message, dblink, str, node->func_name);
7984 }
7985
7986 static void
7987 _rewritePrepareStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, PrepareStmt *node)
7988 {
7989         delay_string_append_char(message, str, "PREPARE \"");
7990         delay_string_append_char(message, str, node->name);
7991         delay_string_append_char(message, str, "\" ");
7992
7993         if (node->argtypes != NIL)
7994         {
7995                 delay_string_append_char(message, str, "(");
7996                 _rewriteNode(BaseSelect, message, dblink, str, node->argtypes);
7997                 delay_string_append_char(message, str, ") ");
7998         }
7999
8000         delay_string_append_char(message, str, "AS ");
8001         _rewriteNode(BaseSelect, message, dblink, str, node->query);
8002 }
8003
8004 static void
8005 _rewriteExecuteStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, ExecuteStmt *node)
8006 {
8007         if (node->into)
8008         {
8009                 IntoClause *into = node->into;
8010                 RangeVar *rel = into->rel;
8011
8012                 delay_string_append_char(message, str, "CREATE ");
8013                 if (rel->istemp == TRUE)
8014                         delay_string_append_char(message, str, "TEMP ");
8015                 delay_string_append_char(message, str, "TABLE ");
8016                 _rewriteNode(BaseSelect, message, dblink, str, into->rel);
8017                 delay_string_append_char(message, str, " AS ");
8018         }
8019
8020         delay_string_append_char(message, str, "EXECUTE \"");
8021         delay_string_append_char(message, str, node->name);
8022         delay_string_append_char(message, str, "\" ");
8023
8024         if (node->params != NIL)
8025         {
8026                 delay_string_append_char(message, str, "(");
8027                 _rewriteNode(BaseSelect, message, dblink, str, node->params);
8028                 delay_string_append_char(message, str, ")");
8029         }
8030 }
8031
8032 static void
8033 _rewriteLockStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, LockStmt *node)
8034 {
8035         delay_string_append_char(message, str, "LOCK TABLE ");
8036         _rewriteNode(BaseSelect, message, dblink, str, node->relations);
8037
8038         delay_string_append_char(message, str, " IN ");
8039         switch (node->mode)
8040         {
8041                 case AccessShareLock:
8042                         delay_string_append_char(message, str, "ACCESS SHARE ");
8043                         break;
8044
8045                 case RowShareLock:
8046                         delay_string_append_char(message, str, "ROW SHARE ");
8047                         break;
8048
8049                 case RowExclusiveLock:
8050                         delay_string_append_char(message, str, "ROW EXCLUSIVE ");
8051                         break;
8052
8053                 case ShareUpdateExclusiveLock:
8054                         delay_string_append_char(message, str, "SHARE UPDATE EXCLUSIVE ");
8055                         break;
8056
8057                 case ShareLock:
8058                         delay_string_append_char(message, str, "SHARE ");
8059                         break;
8060
8061                 case ShareRowExclusiveLock:
8062                         delay_string_append_char(message, str, "SHARE ROW EXCLUSIVE ");
8063                         break;
8064
8065                 case ExclusiveLock:
8066                         delay_string_append_char(message, str, "EXCLUSIVE ");
8067                         break;
8068
8069                 case AccessExclusiveLock:
8070                         delay_string_append_char(message, str, "ACCESS EXCLUSIVE ");
8071                         break;
8072         }
8073         delay_string_append_char(message, str, "MODE");
8074
8075         if (node->nowait == TRUE)
8076                 delay_string_append_char(message, str, " NOWAIT");
8077 }
8078
8079 static void
8080 _rewriteOperatorArgTypes(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *args)
8081 {
8082         TypeName *left, *right;
8083
8084         left = linitial(args);
8085         right = lsecond(args);
8086
8087         if (left)
8088                 _rewriteNode(BaseSelect, message, dblink, str, left);
8089         else
8090                 delay_string_append_char(message, str, "NONE");
8091         delay_string_append_char(message, str, ", ");
8092         if (right)
8093                 _rewriteNode(BaseSelect, message, dblink, str, right);
8094         else
8095                 delay_string_append_char(message, str, "NONE");
8096 }
8097
8098 static void
8099 _rewriteCommentStmt(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CommentStmt *node)
8100 {
8101         TypeName *t;
8102         Value *v;
8103         char buf[16];
8104
8105         delay_string_append_char(message, str, "COMMENT ON ");
8106
8107         switch (node->objtype)
8108         {
8109                 case OBJECT_AGGREGATE:
8110                         delay_string_append_char(message, str, "AGGREGATE ");
8111                         _rewriteFuncName(BaseSelect, message, dblink, str, node->objname);
8112                         delay_string_append_char(message, str, "(");
8113
8114                         t = linitial(node->objargs);
8115                         if (t)
8116                                 _rewriteNode(BaseSelect, message, dblink, str, t);
8117                         else
8118                                 delay_string_append_char(message, str, "*");
8119                         delay_string_append_char(message, str, ")");
8120                         break;
8121
8122                 case OBJECT_FUNCTION:
8123                         delay_string_append_char(message, str, "FUNCTION ");
8124                         _rewriteFuncName(BaseSelect, message, dblink, str, node->objname);
8125                         delay_string_append_char(message, str, "(");
8126                         _rewriteNode(BaseSelect, message, dblink, str, node->objargs);
8127                         delay_string_append_char(message, str, ")");
8128                         break;
8129
8130                 case OBJECT_OPERATOR:
8131                         delay_string_append_char(message, str, "OPERATOR ");
8132                         _rewriteOperatorName(BaseSelect, message, dblink, str, node->objname);
8133                         delay_string_append_char(message, str, "(");
8134                         _rewriteOperatorArgTypes(BaseSelect, message, dblink, str, node->objargs);
8135                         delay_string_append_char(message, str, ")");
8136                         break;
8137
8138                 case OBJECT_CONSTRAINT:
8139                         delay_string_append_char(message, str, "CONSTRAINT \"");
8140                         v = lsecond(node->objname);
8141                         delay_string_append_char(message, str, v->val.str);
8142                         delay_string_append_char(message, str, "\" ON ");
8143                         _rewriteFuncName(BaseSelect, message, dblink, str, linitial(node->objargs));
8144                         break;
8145
8146                 case OBJECT_RULE:
8147                         delay_string_append_char(message, str, "RULE \"");
8148                         v = lsecond(node->objname);
8149                         delay_string_append_char(message, str, v->val.str);
8150                         delay_string_append_char(message, str, "\" ON ");
8151                         _rewriteFuncName(BaseSelect, message, dblink, str, linitial(node->objargs));
8152                         break;
8153
8154                 case OBJECT_TRIGGER:
8155                         delay_string_append_char(message, str, "TRIGGER \"");
8156                         v = lsecond(node->objname);
8157                         delay_string_append_char(message, str, v->val.str);
8158                         delay_string_append_char(message, str, "\" ON ");
8159                         _rewriteFuncName(BaseSelect, message, dblink, str, linitial(node->objargs));
8160                         break;
8161
8162                 case OBJECT_OPCLASS:
8163                         delay_string_append_char(message, str, "OPERATOR CLASS ");
8164                         _rewriteFuncName(BaseSelect, message, dblink, str, node->objname);
8165                         delay_string_append_char(message, str, " USING ");
8166                         v = linitial(node->objargs);
8167                         delay_string_append_char(message, str, v->val.str);
8168                         break;
8169
8170                 case OBJECT_LARGEOBJECT:
8171                         delay_string_append_char(message, str, "LARGE OBJECT ");
8172                         v = linitial(node->objname);
8173                         if (IsA(v, String))
8174                                 delay_string_append_char(message, str, v->val.str);
8175                         else if (IsA(v, Integer))
8176                         {
8177                                 snprintf(buf, 16, "%ld", v->val.ival);
8178                                 delay_string_append_char(message, str, buf);
8179                         }
8180
8181                 case OBJECT_CAST:
8182                         delay_string_append_char(message, str, "CAST (");
8183                         _rewriteNode(BaseSelect, message, dblink, str, linitial(node->objname));
8184                         delay_string_append_char(message, str, " AS ");
8185                         _rewriteNode(BaseSelect, message, dblink, str, linitial(node->objargs));
8186                         delay_string_append_char(message, str, ")");
8187                         break;
8188
8189                 case OBJECT_LANGUAGE:
8190                         delay_string_append_char(message, str, "LANGUAGE ");
8191                         _rewriteFuncName(BaseSelect, message, dblink, str, node->objname);
8192                         break;
8193
8194                 default:
8195                         switch (node->objtype)
8196                         {
8197                                 case OBJECT_COLUMN:
8198                                         delay_string_append_char(message, str, "COLUMN ");
8199                                         break;
8200                                 case OBJECT_DATABASE:
8201                                         delay_string_append_char(message, str, "DATABASE ");
8202                                         break;
8203                                 case OBJECT_SCHEMA:
8204                                         delay_string_append_char(message, str, "SCHEMA ");
8205                                         break;
8206                                 case OBJECT_INDEX:
8207                                         delay_string_append_char(message, str, "INDEX ");
8208                                         break;
8209                                 case OBJECT_SEQUENCE:
8210                                         delay_string_append_char(message, str, "SEQUENCE ");
8211                                         break;
8212                                 case OBJECT_TABLE:
8213                                         delay_string_append_char(message, str, "TABLE ");
8214                                         break;
8215                                 case OBJECT_DOMAIN:
8216                                         delay_string_append_char(message, str, "DOMAIN ");
8217                                         break;
8218                                 case OBJECT_TYPE:
8219                                         delay_string_append_char(message, str, "TYPE ");
8220                                         break;
8221                                 case OBJECT_VIEW:
8222                                         delay_string_append_char(message, str, "VIEW ");
8223                                         break;
8224                                 default:
8225                                         break;
8226                         }
8227                         _rewriteFuncName(BaseSelect, message, dblink, str, node->objname);
8228                         break;
8229         }
8230
8231         delay_string_append_char(message, str, " IS ");
8232         if (node->comment)
8233         {
8234                 delay_string_append_char(message, str, "'");
8235                 delay_string_append_char(message, str, node->comment);
8236                 delay_string_append_char(message, str, "'");
8237         }
8238         else
8239                 delay_string_append_char(message, str, "NULL");
8240 }
8241
8242 static void
8243 _rewriteRangeSubselect(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RangeSubselect *node)
8244 {
8245         int last = message->current_select;
8246         Alias *alias = node->alias;
8247         char *table_name = alias->aliasname;
8248         int sub_no = message->analyze_num;
8249         int CallFromClause = 0;
8250         int next = message->analyze_num;
8251
8252   if(message->r_code == SELECT_AEXPR)
8253         {
8254                 KeepRewriteQueryReturnCode(message, SELECT_AEXPR_FALSE);
8255                 return;
8256         }
8257
8258         if(message->r_code == SELECT_ANALYZE && message->fromClause)
8259                         CallFromClause = 1;
8260
8261         delay_string_append_char(message, str, "(");
8262         _rewriteNode(BaseSelect, message, dblink, str, node->subquery);
8263         delay_string_append_char(message, str, ")");
8264
8265         if(message->r_code == SELECT_ANALYZE)
8266         {
8267                 AnalyzeSelect *analyze;
8268                 analyze=message->analyze[sub_no];
8269
8270                 if(node->alias && node->alias->colnames)
8271                 {
8272                         ListCell   *lc;
8273                         int num = list_length(node->alias->colnames);
8274                         int ret_num = message->analyze[last + 1]->select_ret->col_num;
8275                         if(num == ret_num)
8276                         {
8277                                 char **col_list;
8278                                 int i = 0;
8279                                 col_list = (char **) palloc(sizeof(char *) * num);
8280
8281                                 foreach(lc,node->alias->colnames)
8282                                 {
8283                                         Node *n = lfirst(lc);
8284                                         Value *value = (Value *) n;
8285                                         col_list[i] = value->val.str;
8286                                         i++;
8287                                 }
8288                                 message->analyze[last+1]->select_ret->col_list = col_list;
8289                         }
8290                 }
8291
8292                 message->analyze[last]->select_range = true;
8293
8294                 pool_debug("_rewriteRangeSubSelect: select range ture %d",sub_no);
8295                 build_range_info(message,NULL,NULL,analyze->select_ret,table_name,last,sub_no);
8296         
8297                 /*2009/07/27*/
8298                 if(CallFromClause)
8299                 {
8300                         int temp = message->current_select;
8301                         /* now Subquery's current_select is set
8302                          * change the current_select
8303                          */
8304                         message->current_select = last;
8305                         build_virtual_table(message,node,next);
8306                         message->current_select = temp;
8307                 }
8308         } 
8309         else if(message->r_code == SELECT_DEFAULT && message->ignore_rewrite == -1)
8310         {
8311                 Alias *alias = (Alias *) node->alias;
8312                 delay_string_append_char(message, str, " AS ");
8313                 delay_string_append_char(message, str, alias->aliasname);
8314                 delay_string_append_char(message, str, " ");
8315
8316                 if (alias->colnames)
8317                 {
8318                         AnalyzeSelect *analyze;
8319                         int ret_num;
8320                         int i;
8321                         analyze = message->analyze[last + 1];
8322                         ret_num = analyze->select_ret->col_num;
8323                         delay_string_append_char(message, str, "(");
8324
8325                         for (i = 0; i< ret_num; i++)
8326                         {
8327                                 char buf[16];   
8328                                 snprintf(buf, 16, "%d", analyze->select_ret->return_list[i]);
8329                                 delay_string_append_char(message, str," \"pool_c$");
8330                                 delay_string_append_char(message, str,buf);
8331                                 delay_string_append_char(message, str,"\"");
8332                                 if(i != ret_num -1)
8333                                         delay_string_append_char(message, str,",");     
8334                         }
8335                         delay_string_append_char(message, str, ")");
8336                 }
8337         } else {
8338                 _rewriteNode(BaseSelect, message, dblink, str, node->alias);
8339         }
8340         
8341 }
8342
8343 static void
8344 _rewriteRangeFunction(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, RangeFunction *node)
8345 {
8346         _rewriteNode(BaseSelect, message, dblink, str, node->funccallnode);
8347         if (node->alias)
8348         {
8349                 _rewriteNode(BaseSelect, message, dblink, str, node->alias);
8350         }
8351
8352         if (node->coldeflist)
8353         {
8354                 delay_string_append_char(message, str, " (");
8355                 _rewriteNode(BaseSelect, message, dblink, str, node->coldeflist);
8356                 delay_string_append_char(message, str, ")");
8357         }
8358 }
8359
8360 static void
8361 _rewriteWithDefinition(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, List *def_list)
8362 {
8363         int oid = 0;
8364
8365         if (list_length(def_list) == 1)
8366         {
8367                 DefElem *elem;
8368                 Value *v;
8369
8370                 elem = linitial(def_list);
8371                 v = (Value *)elem->arg;
8372                 if (strcmp(elem->defname, "oids") == 0)
8373                 {
8374                         Value *v = (Value *)elem->arg;
8375                         if (v->val.ival == 1)
8376                                 delay_string_append_char(message, str, " WITH OIDS ");
8377                         else
8378                                 delay_string_append_char(message, str, " WITHOUT OIDS ");
8379                         oid = 1;
8380                 }
8381         }
8382
8383         if (oid == 1)
8384                 return;
8385
8386         delay_string_append_char(message, str, " WITH ");
8387         _rewriteDefinition(BaseSelect, message, dblink, str, def_list);
8388 }
8389
8390 static void
8391 _rewriteCurrentOfExpr(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, CurrentOfExpr *node)
8392 {
8393         delay_string_append_char(message, str, "CURRENT OF ");
8394         if (node->cursor_name == NULL)
8395         {
8396                 char n[10];
8397                 snprintf(n, sizeof(n), "$%d", node->cursor_param);
8398                 delay_string_append_char(message, str, n);
8399         }
8400         else
8401                 delay_string_append_char(message, str, node->cursor_name);
8402 }
8403
8404 /*
8405  * _rewriteNode -
8406  *        converts a Node into ascii string and append it to 'str'
8407  */
8408 static void
8409 _rewriteNode(Node *BaseSelect, RewriteQuery *message, ConInfoTodblink *dblink, String *str, void *obj)
8410 {
8411         if(!obj)
8412                 return;
8413         else if (IsA(obj, List) ||IsA(obj, IntList) || IsA(obj, OidList))
8414                 _rewriteList(BaseSelect, message, dblink, str, obj);
8415         else if (IsA(obj, Integer) ||
8416                          IsA(obj, Float) ||
8417                          IsA(obj, String) ||
8418                          IsA(obj, BitString))
8419         {
8420                 /* nodeRead does not want to see { } around these! */
8421                 _rewriteValue(BaseSelect, message, dblink, str, obj);
8422         }
8423         else
8424         {
8425                 switch (nodeTag(obj))
8426                 {
8427                         case T_Alias:
8428                                 _rewriteAlias(BaseSelect, message, dblink, str, obj);
8429                                 break;
8430                         case T_RangeVar:
8431                                 _rewriteRangeVar(BaseSelect, message, dblink, str, obj);
8432                                 break;
8433                         case T_Var:
8434                                 _rewriteVar(BaseSelect, message, dblink, str, obj);
8435                                 break;
8436                         case T_Const:
8437                                 _rewriteConst(BaseSelect, message, dblink, str, obj);
8438                                 break;
8439                         case T_Param:
8440                                 _rewriteParam(BaseSelect, message, dblink, str, obj);
8441                                 break;
8442                         case T_Aggref:
8443                                 _rewriteAggref(BaseSelect, message, dblink, str, obj);
8444                                 break;
8445                         case T_ArrayRef:
8446                                 _rewriteArrayRef(BaseSelect, message, dblink, str, obj);
8447                                 break;
8448                         case T_FuncExpr:
8449                                 _rewriteFuncExpr(BaseSelect, message, dblink, str, obj);
8450                                 break;
8451                         case T_OpExpr:
8452                                 _rewriteOpExpr(BaseSelect, message, dblink, str, obj);
8453                                 break;
8454                         case T_DistinctExpr:
8455                                 _rewriteDistinctExpr(BaseSelect, message, dblink, str, obj);
8456                                 break;
8457                         case T_ScalarArrayOpExpr:
8458                                 _rewriteScalarArrayOpExpr(BaseSelect, message, dblink, str, obj);
8459                                 break;
8460                         case T_BoolExpr:
8461                                 _rewriteBoolExpr(BaseSelect, message, dblink, str, obj);
8462                                 break;
8463                         case T_SubLink:
8464                                 _rewriteSubLink(BaseSelect, message, dblink, str, obj);
8465                                 break;
8466                         case T_SubPlan:
8467                                 _rewriteSubPlan(BaseSelect, message, dblink, str, obj);
8468                                 break;
8469                         case T_FieldSelect:
8470                                 _rewriteFieldSelect(BaseSelect, message, dblink, str, obj);
8471                                 break;
8472                         case T_FieldStore:
8473                                 _rewriteFieldStore(BaseSelect, message, dblink, str, obj);
8474                                 break;
8475                         case T_RelabelType:
8476                                 _rewriteRelabelType(BaseSelect, message, dblink, str, obj);
8477                                 break;
8478                         case T_ConvertRowtypeExpr:
8479                                 _rewriteConvertRowtypeExpr(BaseSelect, message, dblink, str, obj);
8480                                 break;
8481                         case T_CaseExpr:
8482                                 _rewriteCaseExpr(BaseSelect, message, dblink, str, obj);
8483                                 break;
8484                         case T_CaseWhen:
8485                                 _rewriteCaseWhen(BaseSelect, message, dblink, str, obj);
8486                                 break;
8487                         case T_CaseTestExpr:
8488                                 _rewriteCaseTestExpr(BaseSelect, message, dblink, str, obj);
8489                                 break;
8490                         case T_ArrayExpr:
8491                                 _rewriteArrayExpr(BaseSelect, message, dblink, str, obj);
8492                                 break;
8493                         case T_RowExpr:
8494                                 _rewriteRowExpr(BaseSelect, message, dblink, str, obj);
8495                                 break;
8496                         case T_CoalesceExpr:
8497                                 _rewriteCoalesceExpr(BaseSelect, message, dblink, str, obj);
8498                                 break;
8499                         case T_MinMaxExpr:
8500                                 _rewriteMinMaxExpr(BaseSelect, message, dblink, str, obj);
8501                                 break;
8502                         case T_NullIfExpr:
8503                                 _rewriteNullIfExpr(BaseSelect, message, dblink, str, obj);
8504                                 break;
8505                         case T_NullTest:
8506                                 _rewriteNullTest(BaseSelect, message, dblink, str, obj);
8507                                 break;
8508                         case T_BooleanTest:
8509                                 _rewriteBooleanTest(BaseSelect, message, dblink, str, obj);
8510                                 break;
8511                         case T_CoerceToDomain:
8512                                 _rewriteCoerceToDomain(BaseSelect, message, dblink, str, obj);
8513                                 break;
8514                         case T_CoerceToDomainValue:
8515                                 _rewriteCoerceToDomainValue(BaseSelect, message, dblink, str, obj);
8516                                 break;
8517                         case T_SetToDefault:
8518                                 _rewriteSetToDefault(BaseSelect, message, dblink, str, obj);
8519                                 break;
8520                         case T_TargetEntry:
8521                                 _rewriteTargetEntry(BaseSelect, message, dblink, str, obj);
8522                                 break;
8523                         case T_RangeTblRef:
8524                                 _rewriteRangeTblRef(BaseSelect, message, dblink, str, obj);
8525                                 break;
8526                         case T_JoinExpr:
8527                                 _rewriteJoinExpr(BaseSelect, message, dblink, str, obj);
8528                                 break;
8529                         case T_FromExpr:
8530                                 _rewriteFromExpr(BaseSelect, message, dblink, str, obj);
8531                                 break;
8532
8533                         case T_CreateStmt:
8534                                 _rewriteCreateStmt(BaseSelect, message, dblink, str, obj);
8535                                 break;
8536                         case T_IndexStmt:
8537                                 _rewriteIndexStmt(BaseSelect, message, dblink, str, obj);
8538                                 break;
8539                         case T_NotifyStmt:
8540                                 _rewriteNotifyStmt(BaseSelect, message, dblink, str, obj);
8541                                 break;
8542                         case T_DeclareCursorStmt:
8543                                 _rewriteDeclareCursorStmt(BaseSelect, message, dblink, str, obj);
8544                                 break;
8545                         case T_SelectStmt:
8546                                         _rewriteSelectStmt(BaseSelect, message, dblink, str, obj);
8547                                 break;
8548                         case T_ColumnDef:
8549                                 _rewriteColumnDef(BaseSelect, message, dblink, str, obj);
8550                                 break;
8551                         case T_TypeName:
8552                                 _rewriteTypeName(BaseSelect, message, dblink, str, obj);
8553                                 break;
8554                         case T_TypeCast:
8555                                 _rewriteTypeCast(BaseSelect, message, dblink, str, obj);
8556                                 break;
8557                         case T_IndexElem:
8558                                 _rewriteIndexElem(BaseSelect, message, dblink, str, obj);
8559                                 break;
8560                         case T_SortClause:
8561                                 _rewriteSortClause(BaseSelect, message, dblink, str, obj);
8562                                 break;
8563                         case T_GroupClause:
8564                                 _rewriteGroupClause(BaseSelect, message, dblink, str, obj);
8565                                 break;
8566                         case T_SetOperationStmt:
8567                                 _rewriteSetOperationStmt(BaseSelect, message, dblink, str, obj);
8568                                 break;
8569 /*                      case T_RangeTblEntry:
8570                                 _rewriteRangeTblEntry(BaseSelect, message, dblink, str, obj);
8571                                 break;*/
8572                         case T_A_Expr:
8573                                 _rewriteAExpr(BaseSelect, message, dblink, str, obj);
8574                                 break;
8575                         case T_ColumnRef:
8576                                 _rewriteColumnRef(BaseSelect, message, dblink, str, obj);
8577                                 break;
8578                         case T_ParamRef:
8579                                 _rewriteParamRef(BaseSelect, message, dblink, str, obj);
8580                                 break;
8581                         case T_A_Const:
8582                                 _rewriteAConst(BaseSelect, message, dblink, str, obj);
8583                                 break;
8584                         case T_A_Indices:
8585                                 _rewriteA_Indices(BaseSelect, message, dblink, str, obj);
8586                                 break;
8587                         case T_A_Indirection:
8588                                 _rewriteA_Indirection(BaseSelect, message, dblink, str, obj);
8589                                 break;
8590                         case T_ResTarget:
8591                                 _rewriteResTarget(BaseSelect, message, dblink, str, obj);
8592                                 break;
8593                         case T_Constraint:
8594                                 _rewriteConstraint(BaseSelect, message, dblink, str, obj);
8595                                 break;
8596                         case T_FkConstraint:
8597                                 _rewriteFkConstraint(BaseSelect, message, dblink, str, obj);
8598                                 break;
8599                         case T_FuncCall:
8600                                 _rewriteFuncCall(BaseSelect, message, dblink, str, obj);
8601                                 break;
8602                         case T_DefElem:
8603                                 _rewriteDefElem(BaseSelect, message, dblink, str, obj);
8604                                 break;
8605                         case T_LockingClause:
8606                                 _rewriteLockingClause(BaseSelect, message, dblink, str, obj);
8607                                 break;
8608
8609                         case T_SortBy:
8610                                 _rewriteSortBy(BaseSelect, message, dblink, str, obj);
8611                                 break;
8612
8613                         case T_InsertStmt:
8614                                 _rewriteInsertStmt(BaseSelect, message, dblink, str, obj);
8615                                 break;
8616
8617                         case T_UpdateStmt:
8618                                 _rewriteUpdateStmt(BaseSelect, message, dblink, str, obj);
8619                                 break;
8620
8621                         case T_DeleteStmt:
8622                                 _rewriteDeleteStmt(BaseSelect, message, dblink, str, obj);
8623                                 break;
8624
8625                         case T_TransactionStmt:
8626                                 _rewriteTransactionStmt(BaseSelect, message, dblink, str, obj);
8627                                 break;
8628
8629                         case T_TruncateStmt:
8630                                 _rewriteTruncateStmt(BaseSelect, message, dblink, str, obj);
8631                                 break;
8632
8633                         case T_VacuumStmt:
8634                                 _rewriteVacuumStmt(BaseSelect, message, dblink, str, obj);
8635                                 break;
8636
8637                         case T_ExplainStmt:
8638                                 _rewriteExplainStmt(BaseSelect, message, dblink, str, obj);
8639                                 break;
8640
8641                         case T_ClusterStmt:
8642                                 _rewriteClusterStmt(BaseSelect, message, dblink, str, obj);
8643                                 break;
8644
8645                         case T_CheckPointStmt:
8646                                 _rewriteCheckPointStmt(BaseSelect, message, dblink, str, obj);
8647                                 break;
8648
8649                         case T_ClosePortalStmt:
8650                                 _rewriteClosePortalStmt(BaseSelect, message, dblink, str, obj);
8651                                 break;
8652
8653                         case T_ListenStmt:
8654                                 _rewriteListenStmt(BaseSelect, message, dblink, str, obj);
8655                                 break;
8656
8657                         case T_UnlistenStmt:
8658                                 _rewriteUnlistenStmt(BaseSelect, message, dblink, str, obj);
8659                                 break;
8660
8661                         case T_LoadStmt:
8662                                 _rewriteLoadStmt(BaseSelect, message, dblink, str, obj);
8663                                 break;
8664
8665                         case T_CopyStmt:
8666                                 _rewriteCopyStmt(BaseSelect, message, dblink, str, obj);
8667                                 break;
8668
8669                         case T_DeallocateStmt:
8670                                 _rewriteDeallocateStmt(BaseSelect, message, dblink, str, obj);
8671                                 break;
8672
8673                         case T_RenameStmt:
8674                                 _rewriteRenameStmt(BaseSelect, message, dblink, str, obj);
8675                                 break;
8676
8677                         case T_CreateRoleStmt:
8678                                 _rewriteCreateRoleStmt(BaseSelect, message, dblink, str, obj);
8679                                 break;
8680
8681                         case T_AlterRoleStmt:
8682                                 _rewriteAlterRoleStmt(BaseSelect, message, dblink, str, obj);
8683                                 break;
8684
8685                         case T_AlterRoleSetStmt:
8686                                 _rewriteAlterRoleSetStmt(BaseSelect, message, dblink, str, obj);
8687                                 break;
8688
8689                         case T_DropRoleStmt:
8690                                 _rewriteDropRoleStmt(BaseSelect, message, dblink, str, obj);
8691                                 break;
8692
8693                         case T_CreateSchemaStmt:
8694                                 _rewriteCreateSchemaStmt(BaseSelect, message, dblink, str, obj);
8695                                 break;
8696
8697                         case T_VariableSetStmt:
8698                                 _rewriteVariableSetStmt(BaseSelect, message, dblink, str, obj);
8699                                 break;
8700
8701                         case T_VariableShowStmt:
8702                                 _rewriteVariableShowStmt(BaseSelect, message, dblink, str, obj);
8703                                 break;
8704
8705                         case T_ConstraintsSetStmt:
8706                                 _rewriteConstraintsSetStmt(BaseSelect, message, dblink, str, obj);
8707                                 break;
8708
8709                         case T_AlterTableStmt:
8710                                 _rewriteAlterTableStmt(BaseSelect, message, dblink, str, obj);
8711                                 break;
8712
8713                         case T_AlterTableCmd:
8714                                 _rewriteAlterTableCmd(BaseSelect, message, dblink, str, obj);
8715                                 break;
8716
8717                         case T_CreateSeqStmt:
8718                                 _rewriteCreateSeqStmt(BaseSelect, message, dblink, str, obj);
8719                                 break;
8720
8721                         case T_AlterSeqStmt:
8722                                 _rewriteAlterSeqStmt(BaseSelect, message, dblink, str, obj);
8723                                 break;
8724
8725                         case T_CreatePLangStmt:
8726                                 _rewriteCreatePLangStmt(BaseSelect, message, dblink, str, obj);
8727                                 break;
8728
8729                         case T_DropPLangStmt:
8730                                 _rewriteDropPLangStmt(BaseSelect, message, dblink, str, obj);
8731                                 break;
8732
8733                         case T_CreateTableSpaceStmt:
8734                                 _rewriteCreateTableSpaceStmt(BaseSelect, message, dblink, str, obj);
8735                                 break;
8736
8737                         case T_DropTableSpaceStmt:
8738                                 _rewriteDropTableSpaceStmt(BaseSelect, message, dblink, str, obj);
8739                                 break;
8740
8741                         case T_CreateTrigStmt:
8742                                 _rewriteCreateTrigStmt(BaseSelect, message, dblink, str, obj);
8743                                 break;
8744
8745                         case T_DropPropertyStmt:
8746                                 _rewriteDropPropertyStmt(BaseSelect, message, dblink, str, obj);
8747                                 break;
8748
8749                         case T_DefineStmt:
8750                                 _rewriteDefineStmt(BaseSelect, message, dblink, str, obj);
8751                                 break;
8752
8753                         case T_CreateOpClassStmt:
8754                                 _rewriteCreateOpClassStmt(BaseSelect, message, dblink, str, obj);
8755                                 break;
8756
8757                         case T_CreateOpClassItem:
8758                                 _rewriteCreateOpClassItem(BaseSelect, message, dblink, str, obj);
8759                                 break;
8760
8761                         case T_RemoveOpClassStmt:
8762                                 _rewriteRemoveOpClassStmt(BaseSelect, message, dblink, str, obj);
8763                                 break;
8764
8765                         case T_DropStmt:
8766                                 _rewriteDropStmt(BaseSelect, message, dblink, str, obj);
8767                                 break;
8768
8769                         case T_FetchStmt:
8770                                 _rewriteFetchStmt(BaseSelect, message, dblink, str, obj);
8771                                 break;
8772
8773                         case T_GrantStmt:
8774                                 _rewriteGrantStmt(BaseSelect, message, dblink, str, obj);
8775                                 break;
8776
8777                         case T_PrivTarget:
8778                                 _rewritePrivTarget(BaseSelect, message, dblink, str, obj);
8779                                 break;
8780
8781                         case T_FuncWithArgs:
8782                                 _rewriteFuncWithArgs(BaseSelect, message, dblink, str, obj);
8783                                 break;
8784
8785                         case T_FunctionParameter:
8786                                 _rewriteFunctionParameter(BaseSelect, message, dblink, str, obj);
8787                                 break;
8788
8789                         case T_PrivGrantee:
8790                                 _rewritePrivGrantee(BaseSelect, message, dblink, str, obj);
8791                                 break;
8792
8793                         case T_GrantRoleStmt:
8794                                 _rewriteGrantRoleStmt(BaseSelect, message, dblink, str, obj);
8795                                 break;
8796
8797                         case T_CreateFunctionStmt:
8798                                 _rewriteCreateFunctionStmt(BaseSelect, message, dblink, str, obj);
8799                                 break;
8800
8801                         case T_AlterFunctionStmt:
8802                                 _rewriteAlterFunctionStmt(BaseSelect, message, dblink, str, obj);
8803                                 break;
8804
8805                         case T_RemoveFuncStmt:
8806                                 _rewriteRemoveFuncStmt(BaseSelect, message, dblink, str, obj);
8807                                 break;
8808
8809                         case T_CreateCastStmt:
8810                                 _rewriteCreateCastStmt(BaseSelect, message, dblink, str, obj);
8811                                 break;
8812
8813                         case T_DropCastStmt:
8814                                 _rewriteDropCastStmt(BaseSelect, message, dblink, str, obj);
8815                                 break;
8816
8817                         case T_ReindexStmt:
8818                                 _rewriteReindexStmt(BaseSelect, message, dblink, str, obj);
8819                                 break;
8820
8821                         case T_AlterObjectSchemaStmt:
8822                                 _rewriteAlterObjectSchemaStmt(BaseSelect, message, dblink, str, obj);
8823                                 break;
8824
8825                         case T_AlterOwnerStmt:
8826                                 _rewriteAlterOwnerStmt(BaseSelect, message, dblink, str, obj);
8827                                 break;
8828
8829                         case T_RuleStmt:
8830                                 _rewriteRuleStmt(BaseSelect, message, dblink, str, obj);
8831                                 break;
8832
8833                         case T_ViewStmt:
8834                                 _rewriteViewStmt(BaseSelect, message, dblink, str, obj);
8835                                 break;
8836
8837                         case T_CreatedbStmt:
8838                                 _rewriteCreatedbStmt(BaseSelect, message, dblink, str, obj);
8839                                 break;
8840
8841                         case T_AlterDatabaseStmt:
8842                                 _rewriteAlterDatabaseStmt(BaseSelect, message, dblink, str, obj);
8843                                 break;
8844
8845
8846                         case T_AlterDatabaseSetStmt:
8847                                 _rewriteAlterDatabaseSetStmt(BaseSelect, message, dblink, str, obj);
8848                                 break;
8849
8850                         case T_DropdbStmt:
8851                                 _rewriteDropdbStmt(BaseSelect, message, dblink, str, obj);
8852                                 break;
8853
8854                         case T_CreateDomainStmt:
8855                                 _rewriteCreateDomainStmt(BaseSelect, message, dblink, str, obj);
8856                                 break;
8857
8858                         case T_AlterDomainStmt:
8859                                 _rewriteAlterDomainStmt(BaseSelect, message, dblink, str, obj);
8860                                 break;
8861
8862                         case T_CreateConversionStmt:
8863                                 _rewriteCreateConversionStmt(BaseSelect, message, dblink, str, obj);
8864                                 break;
8865
8866                         case T_PrepareStmt:
8867                                 _rewritePrepareStmt(BaseSelect, message, dblink, str, obj);
8868                                 break;
8869
8870                         case T_ExecuteStmt:
8871                                 _rewriteExecuteStmt(BaseSelect, message, dblink, str, obj);
8872                                 break;
8873
8874                         case T_LockStmt:
8875                                 _rewriteLockStmt(BaseSelect, message, dblink, str, obj);
8876                                 break;
8877
8878                         case T_CommentStmt:
8879                                 _rewriteCommentStmt(BaseSelect, message, dblink, str, obj);
8880                                 break;
8881
8882                         case T_RangeSubselect:
8883                                 _rewriteRangeSubselect(BaseSelect, message, dblink, str, obj);
8884                                 break;
8885
8886                         case T_RangeFunction:
8887                                 _rewriteRangeFunction(BaseSelect, message, dblink, str, obj);
8888                                 break;
8889
8890                         case T_CurrentOfExpr:
8891                                 _rewriteCurrentOfExpr(BaseSelect, message, dblink, str, obj);
8892                                 break;
8893
8894                         case T_DiscardStmt:
8895                         case T_CreateOpFamilyStmt:
8896                         case T_AlterOpFamilyStmt:
8897                         case T_RemoveOpFamilyStmt:
8898                         case T_CreateEnumStmt:
8899                         case T_DropOwnedStmt:
8900                         case T_ReassignOwnedStmt:
8901                         case T_AlterTSDictionaryStmt:
8902                         case T_AlterTSConfigurationStmt:
8903                         case T_XmlSerialize:
8904                         case T_InhRelation:
8905                                 break;
8906
8907                         default:
8908                                 KeepRewriteQueryCode(message, SELECT_RELATION_ERROR);
8909                                 break;
8910                 }
8911         }
8912 }
8913
8914
8915 /*
8916  * nodeToString -
8917  *         returns the ascii representation of the Node as a palloc'd string
8918  */
8919 void
8920 nodeToRewriteString(RewriteQuery *message, ConInfoTodblink *dblink, void *obj)
8921 {
8922         String *str;
8923
8924         str = init_string("");
8925         message->analyze_num = 0;
8926         _rewriteNode(NULL, message, dblink, str, obj);
8927         message->rewrite_query = str->data;
8928 }