* scanNSItemForColumn * Search the column names of a single namespace item for the given name. * If found, return an appropriate Var node, else return NULL. * If the name proves ambiguous within this nsitem, raise error. * * Side effect: if we find a match, mark the corresponding RTE as requiring * read access for the column. */
| 674 | * read access for the column. |
| 675 | */ |
| 676 | Node * |
| 677 | scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, |
| 678 | int sublevels_up, const char *colname, int location) |
| 679 | { |
| 680 | RangeTblEntry *rte = nsitem->p_rte; |
| 681 | int attnum; |
| 682 | Var *var; |
| 683 | |
| 684 | /* |
| 685 | * Scan the nsitem's column names (or aliases) for a match. Complain if |
| 686 | * multiple matches. |
| 687 | */ |
| 688 | attnum = scanRTEForColumn(pstate, rte, nsitem->p_names, |
| 689 | colname, location, |
| 690 | 0, NULL); |
| 691 | |
| 692 | if (attnum == InvalidAttrNumber) |
| 693 | return NULL; /* Return NULL if no match */ |
| 694 | |
| 695 | /* In constraint check, no system column is allowed except tableOid */ |
| 696 | if (pstate->p_expr_kind == EXPR_KIND_CHECK_CONSTRAINT && |
| 697 | attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber) |
| 698 | ereport(ERROR, |
| 699 | (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), |
| 700 | errmsg("system column \"%s\" reference in check constraint is invalid", |
| 701 | colname), |
| 702 | parser_errposition(pstate, location))); |
| 703 | |
| 704 | /* In generated column, no system column is allowed except tableOid */ |
| 705 | if (pstate->p_expr_kind == EXPR_KIND_GENERATED_COLUMN && |
| 706 | attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber) |
| 707 | ereport(ERROR, |
| 708 | (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), |
| 709 | errmsg("cannot use system column \"%s\" in column generation expression", |
| 710 | colname), |
| 711 | parser_errposition(pstate, location))); |
| 712 | |
| 713 | /* Found a valid match, so build a Var */ |
| 714 | if (attnum > InvalidAttrNumber) |
| 715 | { |
| 716 | /* Get attribute data from the ParseNamespaceColumn array */ |
| 717 | ParseNamespaceColumn *nscol = &nsitem->p_nscolumns[attnum - 1]; |
| 718 | |
| 719 | /* Complain if dropped column. See notes in scanRTEForColumn. */ |
| 720 | if (nscol->p_varno == 0) |
| 721 | ereport(ERROR, |
| 722 | (errcode(ERRCODE_UNDEFINED_COLUMN), |
| 723 | errmsg("column \"%s\" of relation \"%s\" does not exist", |
| 724 | colname, |
| 725 | nsitem->p_names->aliasname))); |
| 726 | |
| 727 | var = makeVar(nscol->p_varno, |
| 728 | nscol->p_varattno, |
| 729 | nscol->p_vartype, |
| 730 | nscol->p_vartypmod, |
| 731 | nscol->p_varcollid, |
| 732 | sublevels_up); |
| 733 | /* makeVar doesn't offer parameters for these, so set them by hand: */ |
no test coverage detected