|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.35 2000/03/14 23:06:32 thomas Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.36 2000/03/16 06:35:07 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -103,6 +103,11 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
|
103 | 103 |
|
104 | 104 | result = (Node *) relabel;
|
105 | 105 | }
|
| 106 | + else if (typeInheritsFrom(inputTypeId, targetTypeId)) |
| 107 | + { |
| 108 | + /* Input class type is a subclass of target, so nothing to do */ |
| 109 | + result = node; |
| 110 | + } |
106 | 111 | else
|
107 | 112 | {
|
108 | 113 | /*
|
@@ -156,62 +161,69 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
|
156 | 161 | bool
|
157 | 162 | can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
|
158 | 163 | {
|
159 |
| - HeapTuple ftup; |
160 | 164 | int i;
|
161 |
| - Type tp; |
| 165 | + HeapTuple ftup; |
162 | 166 | Oid oid_array[FUNC_MAX_ARGS];
|
163 | 167 |
|
164 | 168 | /* run through argument list... */
|
165 | 169 | for (i = 0; i < nargs; i++)
|
166 | 170 | {
|
167 |
| - if (input_typeids[i] != func_typeids[i]) |
168 |
| - { |
| 171 | + Oid inputTypeId = input_typeids[i]; |
| 172 | + Oid targetTypeId = func_typeids[i]; |
169 | 173 |
|
170 |
| - /* |
171 |
| - * one of the known-good transparent conversions? then drop |
172 |
| - * through... |
173 |
| - */ |
174 |
| - if (IS_BINARY_COMPATIBLE(input_typeids[i], func_typeids[i])) |
175 |
| - ; |
| 174 | + /* no problem if same type */ |
| 175 | + if (inputTypeId == targetTypeId) |
| 176 | + continue; |
176 | 177 |
|
177 |
| - /* don't know what to do for the output type? then quit... */ |
178 |
| - else if (func_typeids[i] == InvalidOid) |
179 |
| - return false; |
180 |
| - /* don't know what to do for the input type? then quit... */ |
181 |
| - else if (input_typeids[i] == InvalidOid) |
182 |
| - return false; |
| 178 | + /* |
| 179 | + * one of the known-good transparent conversions? then drop |
| 180 | + * through... |
| 181 | + */ |
| 182 | + if (IS_BINARY_COMPATIBLE(inputTypeId, targetTypeId)) |
| 183 | + continue; |
183 | 184 |
|
184 |
| - /* |
185 |
| - * if not unknown input type, try for explicit conversion |
186 |
| - * using functions... |
187 |
| - */ |
188 |
| - else if (input_typeids[i] != UNKNOWNOID) |
189 |
| - { |
190 |
| - MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid)); |
191 |
| - oid_array[0] = input_typeids[i]; |
192 |
| - |
193 |
| - /* |
194 |
| - * look for a single-argument function named with the |
195 |
| - * target type name |
196 |
| - */ |
197 |
| - ftup = SearchSysCacheTuple(PROCNAME, |
198 |
| - PointerGetDatum(typeidTypeName(func_typeids[i])), |
199 |
| - Int32GetDatum(1), |
200 |
| - PointerGetDatum(oid_array), |
201 |
| - 0); |
202 |
| - |
203 |
| - /* |
204 |
| - * should also check the function return type just to be |
205 |
| - * safe... |
206 |
| - */ |
207 |
| - if (!HeapTupleIsValid(ftup)) |
208 |
| - return false; |
209 |
| - } |
| 185 | + /* don't know what to do for the output type? then quit... */ |
| 186 | + if (targetTypeId == InvalidOid) |
| 187 | + return false; |
| 188 | + /* don't know what to do for the input type? then quit... */ |
| 189 | + if (inputTypeId == InvalidOid) |
| 190 | + return false; |
210 | 191 |
|
211 |
| - tp = typeidType(input_typeids[i]); |
212 |
| - if (typeTypeFlag(tp) == 'c') |
| 192 | + /* |
| 193 | + * If input is an untyped string constant, assume we can |
| 194 | + * convert it to anything except a class type. |
| 195 | + */ |
| 196 | + if (inputTypeId == UNKNOWNOID) |
| 197 | + { |
| 198 | + if (ISCOMPLEX(targetTypeId)) |
213 | 199 | return false;
|
| 200 | + continue; |
214 | 201 | }
|
| 202 | + |
| 203 | + /* |
| 204 | + * If input is a class type that inherits from target, no problem |
| 205 | + */ |
| 206 | + if (typeInheritsFrom(inputTypeId, targetTypeId)) |
| 207 | + continue; |
| 208 | + |
| 209 | + /* |
| 210 | + * Else, try for explicit conversion using functions: |
| 211 | + * look for a single-argument function named with the |
| 212 | + * target type name and accepting the source type. |
| 213 | + */ |
| 214 | + MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid)); |
| 215 | + oid_array[0] = inputTypeId; |
| 216 | + |
| 217 | + ftup = SearchSysCacheTuple(PROCNAME, |
| 218 | + PointerGetDatum(typeidTypeName(targetTypeId)), |
| 219 | + Int32GetDatum(1), |
| 220 | + PointerGetDatum(oid_array), |
| 221 | + 0); |
| 222 | + if (!HeapTupleIsValid(ftup)) |
| 223 | + return false; |
| 224 | + /* |
| 225 | + * should also check the function return type just to be safe... |
| 226 | + */ |
215 | 227 | }
|
216 | 228 |
|
217 | 229 | return true;
|
|
0 commit comments