|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.104 2006/05/3011:58:05 momjian Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.105 2006/05/3012: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 | returnT_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 | +intret=T_ERROR; |
| 1454 | +char*fieldvar; |
| 1455 | +intfl; |
| 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 | +returnT_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 | +returnT_ERROR; |
| 1486 | + |
| 1487 | +switch (ns1->itemtype) |
| 1488 | +{ |
| 1489 | +casePLPGSQL_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 | +returnret; |
| 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 | +intret=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 | +returnT_ERROR; |
| 1542 | +} |
| 1543 | + |
| 1544 | +pfree(cp[0]); |
| 1545 | +pfree(cp[1]); |
| 1546 | + |
| 1547 | +switch (ns1->itemtype) |
| 1548 | +{ |
| 1549 | +casePLPGSQL_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 | +returnret; |
| 1566 | +} |
| 1567 | + |
| 1568 | + |
1441 | 1569 | /*
|
1442 | 1570 | * plpgsql_build_variable - build a datum-array entry of a given
|
1443 | 1571 | * datatype
|
|