|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.104 2006/05/30 11:58:05 momjian Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.105 2006/05/30 12:03:13 momjian Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -884,7 +884,8 @@ plpgsql_parse_dblword(char *word)
|
884 | 884 |
|
885 | 885 | new = palloc(sizeof(PLpgSQL_recfield));
|
886 | 886 | new->dtype = PLPGSQL_DTYPE_RECFIELD;
|
887 |
| - new->fieldname = pstrdup(cp[1]); |
| 887 | + new->fieldindex.fieldname = pstrdup(cp[1]); |
| 888 | + new->fieldindex_flag = RECFIELD_USE_FIELDNAME; |
888 | 889 | new->recparentno = ns->itemno;
|
889 | 890 |
|
890 | 891 | plpgsql_adddatum((PLpgSQL_datum *) new);
|
@@ -990,7 +991,8 @@ plpgsql_parse_tripword(char *word)
|
990 | 991 |
|
991 | 992 | new = palloc(sizeof(PLpgSQL_recfield));
|
992 | 993 | new->dtype = PLPGSQL_DTYPE_RECFIELD;
|
993 |
| - new->fieldname = pstrdup(cp[2]); |
| 994 | + new->fieldindex.fieldname = pstrdup(cp[2]); |
| 995 | + new->fieldindex_flag = RECFIELD_USE_FIELDNAME; |
994 | 996 | new->recparentno = ns->itemno;
|
995 | 997 |
|
996 | 998 | plpgsql_adddatum((PLpgSQL_datum *) new);
|
@@ -1438,6 +1440,132 @@ plpgsql_parse_dblwordrowtype(char *word)
|
1438 | 1440 | return T_DTYPE;
|
1439 | 1441 | }
|
1440 | 1442 |
|
| 1443 | +/* ---------- |
| 1444 | + * plpgsql_parse_recindex |
| 1445 | + * lookup associative index into record |
| 1446 | + * ---------- |
| 1447 | + */ |
| 1448 | +int |
| 1449 | +plpgsql_parse_recindex(char *word) |
| 1450 | +{ |
| 1451 | + PLpgSQL_nsitem *ns1, *ns2; |
| 1452 | + char *cp[2]; |
| 1453 | + int ret = T_ERROR; |
| 1454 | + char *fieldvar; |
| 1455 | + int fl; |
| 1456 | + |
| 1457 | + /* Do case conversion and word separation */ |
| 1458 | + plpgsql_convert_ident(word, cp, 2); |
| 1459 | + Assert(cp[1] != NULL); |
| 1460 | + |
| 1461 | + /* cleanup the "(identifier)" string to "identifier" */ |
| 1462 | + fieldvar = cp[1]; |
| 1463 | + Assert(*fieldvar == '('); |
| 1464 | + ++fieldvar; /* get rid of ( */ |
| 1465 | + |
| 1466 | + fl = strlen(fieldvar); |
| 1467 | + Assert(fieldvar[fl-1] == ')'); |
| 1468 | + fieldvar[fl-1] = 0; /* get rid of ) */ |
| 1469 | + |
| 1470 | + /* |
| 1471 | + * Lookup the first word |
| 1472 | + */ |
| 1473 | + ns1 = plpgsql_ns_lookup(cp[0], NULL); |
| 1474 | + if ( ns1 == NULL ) |
| 1475 | + { |
| 1476 | + pfree(cp[0]); |
| 1477 | + pfree(cp[1]); |
| 1478 | + return T_ERROR; |
| 1479 | + } |
| 1480 | + |
| 1481 | + ns2 = plpgsql_ns_lookup(fieldvar, NULL); |
| 1482 | + pfree(cp[0]); |
| 1483 | + pfree(cp[1]); |
| 1484 | + if ( ns2 == NULL ) /* name lookup failed */ |
| 1485 | + return T_ERROR; |
| 1486 | + |
| 1487 | + switch (ns1->itemtype) |
| 1488 | + { |
| 1489 | + case PLPGSQL_NSTYPE_REC: |
| 1490 | + { |
| 1491 | + /* |
| 1492 | + * First word is a record name, so second word must be an |
| 1493 | + * variable holding the field name in this record. |
| 1494 | + */ |
| 1495 | + if ( ns2->itemtype == PLPGSQL_NSTYPE_VAR ) { |
| 1496 | + PLpgSQL_recfield *new; |
| 1497 | + |
| 1498 | + new = palloc(sizeof(PLpgSQL_recfield)); |
| 1499 | + new->dtype = PLPGSQL_DTYPE_RECFIELD; |
| 1500 | + new->fieldindex.indexvar_no = ns2->itemno; |
| 1501 | + new->fieldindex_flag = RECFIELD_USE_INDEX_VAR; |
| 1502 | + new->recparentno = ns1->itemno; |
| 1503 | + |
| 1504 | + plpgsql_adddatum((PLpgSQL_datum *) new); |
| 1505 | + |
| 1506 | + plpgsql_yylval.scalar = (PLpgSQL_datum *) new; |
| 1507 | + ret = T_SCALAR; |
| 1508 | + } |
| 1509 | + break; |
| 1510 | + } |
| 1511 | + default: |
| 1512 | + break; |
| 1513 | + } |
| 1514 | + return ret; |
| 1515 | +} |
| 1516 | + |
| 1517 | + |
| 1518 | +/* ---------- |
| 1519 | + * plpgsql_parse_recfieldnames |
| 1520 | + * create fieldnames of a record |
| 1521 | + * ---------- |
| 1522 | + */ |
| 1523 | +int |
| 1524 | +plpgsql_parse_recfieldnames(char *word) |
| 1525 | +{ |
| 1526 | + PLpgSQL_nsitem *ns1; |
| 1527 | + char *cp[2]; |
| 1528 | + int ret = T_ERROR; |
| 1529 | + |
| 1530 | + /* Do case conversion and word separation */ |
| 1531 | + plpgsql_convert_ident(word, cp, 2); |
| 1532 | + |
| 1533 | + /* |
| 1534 | + * Lookup the first word |
| 1535 | + */ |
| 1536 | + ns1 = plpgsql_ns_lookup(cp[0], NULL); |
| 1537 | + if ( ns1 == NULL ) |
| 1538 | + { |
| 1539 | + pfree(cp[0]); |
| 1540 | + pfree(cp[1]); |
| 1541 | + return T_ERROR; |
| 1542 | + } |
| 1543 | + |
| 1544 | + pfree(cp[0]); |
| 1545 | + pfree(cp[1]); |
| 1546 | + |
| 1547 | + switch (ns1->itemtype) |
| 1548 | + { |
| 1549 | + case PLPGSQL_NSTYPE_REC: |
| 1550 | + { |
| 1551 | + PLpgSQL_recfieldproperties *new; |
| 1552 | + |
| 1553 | + new = palloc(sizeof(PLpgSQL_recfieldproperties)); |
| 1554 | + new->dtype = PLPGSQL_DTYPE_RECFIELDNAMES; |
| 1555 | + new->recparentno = ns1->itemno; |
| 1556 | + new->save_fieldnames = NULL; |
| 1557 | + plpgsql_adddatum((PLpgSQL_datum *) new); |
| 1558 | + plpgsql_yylval.scalar = (PLpgSQL_datum *) new; |
| 1559 | + ret = T_SCALAR; /* ??? */ |
| 1560 | + break; |
| 1561 | + } |
| 1562 | + default: |
| 1563 | + break; |
| 1564 | + } |
| 1565 | + return ret; |
| 1566 | +} |
| 1567 | + |
| 1568 | + |
1441 | 1569 | /*
|
1442 | 1570 | * plpgsql_build_variable - build a datum-array entry of a given
|
1443 | 1571 | * datatype
|
|
0 commit comments