* resolve_column_ref attempt to resolve a ColumnRef as a plpgsql var * * Returns the translated node structure, or NULL if name not found * * error_if_no_field tells whether to throw error or quietly return NULL if * we are able to match a record/row name but don't find a field name match. */
| 1195 | * we are able to match a record/row name but don't find a field name match. |
| 1196 | */ |
| 1197 | static Node * |
| 1198 | resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr, |
| 1199 | ColumnRef *cref, bool error_if_no_field) |
| 1200 | { |
| 1201 | PLpgSQL_execstate *estate; |
| 1202 | PLpgSQL_nsitem *nse; |
| 1203 | const char *name1; |
| 1204 | const char *name2 = NULL; |
| 1205 | const char *name3 = NULL; |
| 1206 | const char *colname = NULL; |
| 1207 | int nnames; |
| 1208 | int nnames_scalar = 0; |
| 1209 | int nnames_wholerow = 0; |
| 1210 | int nnames_field = 0; |
| 1211 | |
| 1212 | /* |
| 1213 | * We use the function's current estate to resolve parameter data types. |
| 1214 | * This is really pretty bogus because there is no provision for updating |
| 1215 | * plans when those types change ... |
| 1216 | */ |
| 1217 | estate = expr->func->cur_estate; |
| 1218 | |
| 1219 | /*---------- |
| 1220 | * The allowed syntaxes are: |
| 1221 | * |
| 1222 | * A Scalar variable reference, or whole-row record reference. |
| 1223 | * A.B Qualified scalar or whole-row reference, or field reference. |
| 1224 | * A.B.C Qualified record field reference. |
| 1225 | * A.* Whole-row record reference. |
| 1226 | * A.B.* Qualified whole-row record reference. |
| 1227 | *---------- |
| 1228 | */ |
| 1229 | switch (list_length(cref->fields)) |
| 1230 | { |
| 1231 | case 1: |
| 1232 | { |
| 1233 | Node *field1 = (Node *) linitial(cref->fields); |
| 1234 | |
| 1235 | Assert(IsA(field1, String)); |
| 1236 | name1 = strVal(field1); |
| 1237 | nnames_scalar = 1; |
| 1238 | nnames_wholerow = 1; |
| 1239 | break; |
| 1240 | } |
| 1241 | case 2: |
| 1242 | { |
| 1243 | Node *field1 = (Node *) linitial(cref->fields); |
| 1244 | Node *field2 = (Node *) lsecond(cref->fields); |
| 1245 | |
| 1246 | Assert(IsA(field1, String)); |
| 1247 | name1 = strVal(field1); |
| 1248 | |
| 1249 | /* Whole-row reference? */ |
| 1250 | if (IsA(field2, A_Star)) |
| 1251 | { |
| 1252 | /* Set name2 to prevent matches to scalar variables */ |
| 1253 | name2 = "*"; |
| 1254 | nnames_wholerow = 1; |
no test coverage detected