* transformContainerSubscripts() * Transform container (array, etc) subscripting. This is used for both * container fetch and container assignment. * * In a container fetch, we are given a source container value and we produce * an expression that represents the result of extracting a single container * element or a container slice. * * Container assignments are treated basically the sa
| 245 | * isAssignment True if this will become a container assignment. |
| 246 | */ |
| 247 | SubscriptingRef * |
| 248 | transformContainerSubscripts(ParseState *pstate, |
| 249 | Node *containerBase, |
| 250 | Oid containerType, |
| 251 | int32 containerTypMod, |
| 252 | List *indirection, |
| 253 | bool isAssignment) |
| 254 | { |
| 255 | SubscriptingRef *sbsref; |
| 256 | const SubscriptRoutines *sbsroutines; |
| 257 | Oid elementType; |
| 258 | bool isSlice = false; |
| 259 | ListCell *idx; |
| 260 | |
| 261 | /* |
| 262 | * Determine the actual container type, smashing any domain. In the |
| 263 | * assignment case the caller already did this, since it also needs to |
| 264 | * know the actual container type. |
| 265 | */ |
| 266 | if (!isAssignment) |
| 267 | transformContainerType(&containerType, &containerTypMod); |
| 268 | |
| 269 | /* |
| 270 | * Verify that the container type is subscriptable, and get its support |
| 271 | * functions and typelem. |
| 272 | */ |
| 273 | sbsroutines = getSubscriptingRoutines(containerType, &elementType); |
| 274 | if (!sbsroutines) |
| 275 | ereport(ERROR, |
| 276 | (errcode(ERRCODE_DATATYPE_MISMATCH), |
| 277 | errmsg("cannot subscript type %s because it does not support subscripting", |
| 278 | format_type_be(containerType)), |
| 279 | parser_errposition(pstate, exprLocation(containerBase)))); |
| 280 | |
| 281 | /* |
| 282 | * Detect whether any of the indirection items are slice specifiers. |
| 283 | * |
| 284 | * A list containing only simple subscripts refers to a single container |
| 285 | * element. If any of the items are slice specifiers (lower:upper), then |
| 286 | * the subscript expression means a container slice operation. |
| 287 | */ |
| 288 | foreach(idx, indirection) |
| 289 | { |
| 290 | A_Indices *ai = lfirst_node(A_Indices, idx); |
| 291 | |
| 292 | if (ai->is_slice) |
| 293 | { |
| 294 | isSlice = true; |
| 295 | break; |
| 296 | } |
| 297 | } |
| 298 | |
| 299 | /* |
| 300 | * Ready to build the SubscriptingRef node. |
| 301 | */ |
| 302 | sbsref = makeNode(SubscriptingRef); |
| 303 | |
| 304 | sbsref->refcontainertype = containerType; |
no test coverage detected