* Generate a suitable error about a missing RTE. * * Since this is a very common type of error, we work rather hard to * produce a helpful message. */
| 3843 | * produce a helpful message. |
| 3844 | */ |
| 3845 | void |
| 3846 | errorMissingRTE(ParseState *pstate, RangeVar *relation) |
| 3847 | { |
| 3848 | RangeTblEntry *rte; |
| 3849 | const char *badAlias = NULL; |
| 3850 | |
| 3851 | /* |
| 3852 | * Check to see if there are any potential matches in the query's |
| 3853 | * rangetable. (Note: cases involving a bad schema name in the RangeVar |
| 3854 | * will throw error immediately here. That seems OK.) |
| 3855 | */ |
| 3856 | rte = searchRangeTableForRel(pstate, relation); |
| 3857 | |
| 3858 | /* |
| 3859 | * If we found a match that has an alias and the alias is visible in the |
| 3860 | * namespace, then the problem is probably use of the relation's real name |
| 3861 | * instead of its alias, ie "SELECT foo.* FROM foo f". This mistake is |
| 3862 | * common enough to justify a specific hint. |
| 3863 | * |
| 3864 | * If we found a match that doesn't meet those criteria, assume the |
| 3865 | * problem is illegal use of a relation outside its scope, as in the |
| 3866 | * MySQL-ism "SELECT ... FROM a, b LEFT JOIN c ON (a.x = c.y)". |
| 3867 | */ |
| 3868 | if (rte && rte->alias && |
| 3869 | strcmp(rte->eref->aliasname, relation->relname) != 0) |
| 3870 | { |
| 3871 | ParseNamespaceItem *nsitem; |
| 3872 | int sublevels_up; |
| 3873 | |
| 3874 | nsitem = refnameNamespaceItem(pstate, NULL, rte->eref->aliasname, |
| 3875 | relation->location, |
| 3876 | &sublevels_up); |
| 3877 | if (nsitem && nsitem->p_rte == rte) |
| 3878 | badAlias = rte->eref->aliasname; |
| 3879 | } |
| 3880 | |
| 3881 | if (rte) |
| 3882 | ereport(ERROR, |
| 3883 | (errcode(ERRCODE_UNDEFINED_TABLE), |
| 3884 | errmsg("invalid reference to FROM-clause entry for table \"%s\"", |
| 3885 | relation->relname), |
| 3886 | (badAlias ? |
| 3887 | errhint("Perhaps you meant to reference the table alias \"%s\".", |
| 3888 | badAlias) : |
| 3889 | errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.", |
| 3890 | rte->eref->aliasname)), |
| 3891 | parser_errposition(pstate, relation->location))); |
| 3892 | else |
| 3893 | ereport(ERROR, |
| 3894 | (errcode(ERRCODE_UNDEFINED_TABLE), |
| 3895 | errmsg("missing FROM-clause entry for table \"%s\"", |
| 3896 | relation->relname), |
| 3897 | parser_errposition(pstate, relation->location))); |
| 3898 | } |
| 3899 | |
| 3900 | /* |
| 3901 | * Generate a suitable error about a missing column. |
no test coverage detected