* exprTypmod - * returns the type-specific modifier of the expression's result type, * if it can be determined. In many cases, it can't and we return -1. */
| 285 | * if it can be determined. In many cases, it can't and we return -1. |
| 286 | */ |
| 287 | int32 |
| 288 | exprTypmod(const Node *expr) |
| 289 | { |
| 290 | if (!expr) |
| 291 | return -1; |
| 292 | |
| 293 | switch (nodeTag(expr)) |
| 294 | { |
| 295 | case T_Var: |
| 296 | return ((const Var *) expr)->vartypmod; |
| 297 | case T_Const: |
| 298 | return ((const Const *) expr)->consttypmod; |
| 299 | case T_Param: |
| 300 | return ((const Param *) expr)->paramtypmod; |
| 301 | case T_SubscriptingRef: |
| 302 | return ((const SubscriptingRef *) expr)->reftypmod; |
| 303 | case T_FuncExpr: |
| 304 | { |
| 305 | int32 coercedTypmod; |
| 306 | |
| 307 | /* Be smart about length-coercion functions... */ |
| 308 | if (exprIsLengthCoercion(expr, &coercedTypmod)) |
| 309 | return coercedTypmod; |
| 310 | } |
| 311 | break; |
| 312 | case T_NamedArgExpr: |
| 313 | return exprTypmod((Node *) ((const NamedArgExpr *) expr)->arg); |
| 314 | case T_NullIfExpr: |
| 315 | { |
| 316 | /* |
| 317 | * Result is either first argument or NULL, so we can report |
| 318 | * first argument's typmod if known. |
| 319 | */ |
| 320 | const NullIfExpr *nexpr = (const NullIfExpr *) expr; |
| 321 | |
| 322 | return exprTypmod((Node *) linitial(nexpr->args)); |
| 323 | } |
| 324 | break; |
| 325 | case T_SubLink: |
| 326 | { |
| 327 | const SubLink *sublink = (const SubLink *) expr; |
| 328 | |
| 329 | if (sublink->subLinkType == EXPR_SUBLINK || |
| 330 | sublink->subLinkType == ARRAY_SUBLINK) |
| 331 | { |
| 332 | /* get the typmod of the subselect's first target column */ |
| 333 | Query *qtree = (Query *) sublink->subselect; |
| 334 | TargetEntry *tent; |
| 335 | |
| 336 | if (!qtree || !IsA(qtree, Query)) |
| 337 | elog(ERROR, "cannot get type for untransformed sublink"); |
| 338 | tent = linitial_node(TargetEntry, qtree->targetList); |
| 339 | Assert(!tent->resjunk); |
| 340 | return exprTypmod((Node *) tent->expr); |
| 341 | /* note we don't need to care if it's an array */ |
| 342 | } |
| 343 | /* otherwise, result is RECORD or BOOLEAN, typmod is -1 */ |
| 344 | } |
no test coverage detected