PostgreSQL Source Code  git master
parsetree.h File Reference
#include "nodes/parsenodes.h"
Include dependency graph for parsetree.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define rt_fetch(rangetable_index, rangetable)   ((RangeTblEntry *) list_nth(rangetable, (rangetable_index)-1))
 
#define getrelid(rangeindex, rangetable)   (rt_fetch(rangeindex, rangetable)->relid)
 

Functions

char * get_rte_attribute_name (RangeTblEntry *rte, AttrNumber attnum)
 
void get_rte_attribute_type (RangeTblEntry *rte, AttrNumber attnum, Oid *vartype, int32 *vartypmod, Oid *varcollid)
 
bool get_rte_attribute_is_dropped (RangeTblEntry *rte, AttrNumber attnum)
 
TargetEntryget_tle_by_resno (List *tlist, AttrNumber resno)
 
RowMarkClauseget_parse_rowmark (Query *qry, Index rtindex)
 

Macro Definition Documentation

◆ getrelid

#define getrelid (   rangeindex,
  rangetable 
)    (rt_fetch(rangeindex, rangetable)->relid)

◆ rt_fetch

#define rt_fetch (   rangetable_index,
  rangetable 
)    ((RangeTblEntry *) list_nth(rangetable, (rangetable_index)-1))

Function Documentation

◆ get_parse_rowmark()

RowMarkClause* get_parse_rowmark ( Query qry,
Index  rtindex 
)

Definition at line 3054 of file parse_relation.c.

References lfirst, Query::rowMarks, and RowMarkClause::rti.

Referenced by AcquireRewriteLocks(), applyLockingClause(), ApplyRetrieveRule(), fireRIRrules(), and ScanQueryForLocks().

3055 {
3056  ListCell *l;
3057 
3058  foreach(l, qry->rowMarks)
3059  {
3060  RowMarkClause *rc = (RowMarkClause *) lfirst(l);
3061 
3062  if (rc->rti == rtindex)
3063  return rc;
3064  }
3065  return NULL;
3066 }
List * rowMarks
Definition: parsenodes.h:161
#define lfirst(lc)
Definition: pg_list.h:106

◆ get_rte_attribute_is_dropped()

bool get_rte_attribute_is_dropped ( RangeTblEntry rte,
AttrNumber  attnum 
)

Definition at line 2899 of file parse_relation.c.

References Alias::aliasname, Assert, ATTNUM, RangeTblEntry::coltypes, elog, RangeTblEntry::eref, ereport, errcode(), errmsg(), ERROR, RangeTblFunction::funccolcount, RangeTblFunction::funcexpr, RangeTblEntry::funcordinality, RangeTblEntry::functions, get_expr_result_tupdesc(), GETSTRUCT, HeapTupleIsValid, Int16GetDatum, RangeTblEntry::joinaliasvars, lfirst, list_length(), list_nth(), list_nth_oid(), ObjectIdGetDatum, OidIsValid, ReleaseSysCache(), RangeTblEntry::relid, RTE_CTE, RTE_FUNCTION, RTE_JOIN, RTE_NAMEDTUPLESTORE, RTE_RELATION, RTE_SUBQUERY, RTE_TABLEFUNC, RTE_VALUES, RangeTblEntry::rtekind, SearchSysCache2(), and TupleDescAttr.

Referenced by AcquireRewriteLocks().

2900 {
2901  bool result;
2902 
2903  switch (rte->rtekind)
2904  {
2905  case RTE_RELATION:
2906  {
2907  /*
2908  * Plain relation RTE --- get the attribute's catalog entry
2909  */
2910  HeapTuple tp;
2911  Form_pg_attribute att_tup;
2912 
2913  tp = SearchSysCache2(ATTNUM,
2914  ObjectIdGetDatum(rte->relid),
2915  Int16GetDatum(attnum));
2916  if (!HeapTupleIsValid(tp)) /* shouldn't happen */
2917  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
2918  attnum, rte->relid);
2919  att_tup = (Form_pg_attribute) GETSTRUCT(tp);
2920  result = att_tup->attisdropped;
2921  ReleaseSysCache(tp);
2922  }
2923  break;
2924  case RTE_SUBQUERY:
2925  case RTE_TABLEFUNC:
2926  case RTE_VALUES:
2927  case RTE_CTE:
2928 
2929  /*
2930  * Subselect, Table Functions, Values, CTE RTEs never have dropped
2931  * columns
2932  */
2933  result = false;
2934  break;
2935  case RTE_NAMEDTUPLESTORE:
2936  {
2937  /* Check dropped-ness by testing for valid coltype */
2938  if (attnum <= 0 ||
2939  attnum > list_length(rte->coltypes))
2940  elog(ERROR, "invalid varattno %d", attnum);
2941  result = !OidIsValid((list_nth_oid(rte->coltypes, attnum - 1)));
2942  }
2943  break;
2944  case RTE_JOIN:
2945  {
2946  /*
2947  * A join RTE would not have dropped columns when constructed,
2948  * but one in a stored rule might contain columns that were
2949  * dropped from the underlying tables, if said columns are
2950  * nowhere explicitly referenced in the rule. This will be
2951  * signaled to us by a null pointer in the joinaliasvars list.
2952  */
2953  Var *aliasvar;
2954 
2955  if (attnum <= 0 ||
2956  attnum > list_length(rte->joinaliasvars))
2957  elog(ERROR, "invalid varattno %d", attnum);
2958  aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
2959 
2960  result = (aliasvar == NULL);
2961  }
2962  break;
2963  case RTE_FUNCTION:
2964  {
2965  /* Function RTE */
2966  ListCell *lc;
2967  int atts_done = 0;
2968 
2969  /*
2970  * Dropped attributes are only possible with functions that
2971  * return named composite types. In such a case we have to
2972  * look up the result type to see if it currently has this
2973  * column dropped. So first, loop over the funcs until we
2974  * find the one that covers the requested column.
2975  */
2976  foreach(lc, rte->functions)
2977  {
2978  RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
2979 
2980  if (attnum > atts_done &&
2981  attnum <= atts_done + rtfunc->funccolcount)
2982  {
2983  TupleDesc tupdesc;
2984 
2985  tupdesc = get_expr_result_tupdesc(rtfunc->funcexpr,
2986  true);
2987  if (tupdesc)
2988  {
2989  /* Composite data type, e.g. a table's row type */
2990  Form_pg_attribute att_tup;
2991 
2992  Assert(tupdesc);
2993  Assert(attnum - atts_done <= tupdesc->natts);
2994  att_tup = TupleDescAttr(tupdesc,
2995  attnum - atts_done - 1);
2996  return att_tup->attisdropped;
2997  }
2998  /* Otherwise, it can't have any dropped columns */
2999  return false;
3000  }
3001  atts_done += rtfunc->funccolcount;
3002  }
3003 
3004  /* If we get here, must be looking for the ordinality column */
3005  if (rte->funcordinality && attnum == atts_done + 1)
3006  return false;
3007 
3008  /* this probably can't happen ... */
3009  ereport(ERROR,
3010  (errcode(ERRCODE_UNDEFINED_COLUMN),
3011  errmsg("column %d of relation \"%s\" does not exist",
3012  attnum,
3013  rte->eref->aliasname)));
3014  result = false; /* keep compiler quiet */
3015  }
3016  break;
3017  default:
3018  elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
3019  result = false; /* keep compiler quiet */
3020  }
3021 
3022  return result;
3023 }
Oid list_nth_oid(const List *list, int n)
Definition: list.c:432
List * joinaliasvars
Definition: parsenodes.h:995
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
#define Int16GetDatum(X)
Definition: postgres.h:457
int errcode(int sqlerrcode)
Definition: elog.c:575
bool funcordinality
Definition: parsenodes.h:1006
Definition: primnodes.h:163
#define OidIsValid(objectId)
Definition: c.h:586
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
TupleDesc get_expr_result_tupdesc(Node *expr, bool noError)
Definition: funcapi.c:412
void * list_nth(const List *list, int n)
Definition: list.c:410
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:680
#define lfirst(lc)
Definition: pg_list.h:106
char * aliasname
Definition: primnodes.h:42
List * functions
Definition: parsenodes.h:1005
static int list_length(const List *l)
Definition: pg_list.h:89
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1123
RTEKind rtekind
Definition: parsenodes.h:951
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
Alias * eref
Definition: parsenodes.h:1055
List * coltypes
Definition: parsenodes.h:1041

◆ get_rte_attribute_name()

char* get_rte_attribute_name ( RangeTblEntry rte,
AttrNumber  attnum 
)

Definition at line 2671 of file parse_relation.c.

References RangeTblEntry::alias, Alias::aliasname, Alias::colnames, elog, RangeTblEntry::eref, ERROR, get_relid_attribute_name(), InvalidAttrNumber, list_length(), list_nth(), RangeTblEntry::relid, RTE_RELATION, RangeTblEntry::rtekind, and strVal.

Referenced by check_ungrouped_columns_walker(), get_name_for_var_field(), get_variable(), and print_expr().

2672 {
2673  if (attnum == InvalidAttrNumber)
2674  return "*";
2675 
2676  /*
2677  * If there is a user-written column alias, use it.
2678  */
2679  if (rte->alias &&
2680  attnum > 0 && attnum <= list_length(rte->alias->colnames))
2681  return strVal(list_nth(rte->alias->colnames, attnum - 1));
2682 
2683  /*
2684  * If the RTE is a relation, go to the system catalogs not the
2685  * eref->colnames list. This is a little slower but it will give the
2686  * right answer if the column has been renamed since the eref list was
2687  * built (which can easily happen for rules).
2688  */
2689  if (rte->rtekind == RTE_RELATION)
2690  return get_relid_attribute_name(rte->relid, attnum);
2691 
2692  /*
2693  * Otherwise use the column name from eref. There should always be one.
2694  */
2695  if (attnum > 0 && attnum <= list_length(rte->eref->colnames))
2696  return strVal(list_nth(rte->eref->colnames, attnum - 1));
2697 
2698  /* else caller gave us a bogus attnum */
2699  elog(ERROR, "invalid attnum %d for rangetable entry %s",
2700  attnum, rte->eref->aliasname);
2701  return NULL; /* keep compiler quiet */
2702 }
Alias * alias
Definition: parsenodes.h:1054
List * colnames
Definition: primnodes.h:43
#define strVal(v)
Definition: value.h:54
#define ERROR
Definition: elog.h:43
void * list_nth(const List *list, int n)
Definition: list.c:410
char * get_relid_attribute_name(Oid relid, AttrNumber attnum)
Definition: lsyscache.c:801
char * aliasname
Definition: primnodes.h:42
static int list_length(const List *l)
Definition: pg_list.h:89
#define InvalidAttrNumber
Definition: attnum.h:23
RTEKind rtekind
Definition: parsenodes.h:951
#define elog
Definition: elog.h:219
Alias * eref
Definition: parsenodes.h:1055

◆ get_rte_attribute_type()

void get_rte_attribute_type ( RangeTblEntry rte,
AttrNumber  attnum,
Oid vartype,
int32 vartypmod,
Oid varcollid 
)

Definition at line 2709 of file parse_relation.c.

References Alias::aliasname, Assert, ATTNUM, RangeTblEntry::colcollations, RangeTblEntry::coltypes, RangeTblEntry::coltypmods, elog, RangeTblEntry::eref, ereport, errcode(), errmsg(), ERROR, TargetEntry::expr, exprCollation(), exprType(), exprTypmod(), RangeTblFunction::funccolcollations, RangeTblFunction::funccolcount, RangeTblFunction::funccoltypes, RangeTblFunction::funccoltypmods, RangeTblFunction::funcexpr, RangeTblEntry::funcordinality, RangeTblEntry::functions, get_expr_result_type(), get_rel_name(), get_tle_by_resno(), GETSTRUCT, HeapTupleIsValid, Int16GetDatum, INT8OID, InvalidOid, RangeTblEntry::joinaliasvars, lfirst, list_length(), list_nth(), list_nth_int(), list_nth_oid(), NameStr, ObjectIdGetDatum, OidIsValid, ReleaseSysCache(), RangeTblEntry::relid, TargetEntry::resjunk, RTE_CTE, RTE_FUNCTION, RTE_JOIN, RTE_NAMEDTUPLESTORE, RTE_RELATION, RTE_SUBQUERY, RTE_TABLEFUNC, RTE_VALUES, RangeTblEntry::rtekind, SearchSysCache2(), RangeTblEntry::subquery, Query::targetList, TupleDescAttr, TYPEFUNC_COMPOSITE, TYPEFUNC_COMPOSITE_DOMAIN, TYPEFUNC_RECORD, and TYPEFUNC_SCALAR.

Referenced by make_var().

2711 {
2712  switch (rte->rtekind)
2713  {
2714  case RTE_RELATION:
2715  {
2716  /* Plain relation RTE --- get the attribute's type info */
2717  HeapTuple tp;
2718  Form_pg_attribute att_tup;
2719 
2720  tp = SearchSysCache2(ATTNUM,
2721  ObjectIdGetDatum(rte->relid),
2722  Int16GetDatum(attnum));
2723  if (!HeapTupleIsValid(tp)) /* shouldn't happen */
2724  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
2725  attnum, rte->relid);
2726  att_tup = (Form_pg_attribute) GETSTRUCT(tp);
2727 
2728  /*
2729  * If dropped column, pretend it ain't there. See notes in
2730  * scanRTEForColumn.
2731  */
2732  if (att_tup->attisdropped)
2733  ereport(ERROR,
2734  (errcode(ERRCODE_UNDEFINED_COLUMN),
2735  errmsg("column \"%s\" of relation \"%s\" does not exist",
2736  NameStr(att_tup->attname),
2737  get_rel_name(rte->relid))));
2738  *vartype = att_tup->atttypid;
2739  *vartypmod = att_tup->atttypmod;
2740  *varcollid = att_tup->attcollation;
2741  ReleaseSysCache(tp);
2742  }
2743  break;
2744  case RTE_SUBQUERY:
2745  {
2746  /* Subselect RTE --- get type info from subselect's tlist */
2748  attnum);
2749 
2750  if (te == NULL || te->resjunk)
2751  elog(ERROR, "subquery %s does not have attribute %d",
2752  rte->eref->aliasname, attnum);
2753  *vartype = exprType((Node *) te->expr);
2754  *vartypmod = exprTypmod((Node *) te->expr);
2755  *varcollid = exprCollation((Node *) te->expr);
2756  }
2757  break;
2758  case RTE_FUNCTION:
2759  {
2760  /* Function RTE */
2761  ListCell *lc;
2762  int atts_done = 0;
2763 
2764  /* Identify which function covers the requested column */
2765  foreach(lc, rte->functions)
2766  {
2767  RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
2768 
2769  if (attnum > atts_done &&
2770  attnum <= atts_done + rtfunc->funccolcount)
2771  {
2772  TypeFuncClass functypclass;
2773  Oid funcrettype;
2774  TupleDesc tupdesc;
2775 
2776  attnum -= atts_done; /* now relative to this func */
2777  functypclass = get_expr_result_type(rtfunc->funcexpr,
2778  &funcrettype,
2779  &tupdesc);
2780 
2781  if (functypclass == TYPEFUNC_COMPOSITE ||
2782  functypclass == TYPEFUNC_COMPOSITE_DOMAIN)
2783  {
2784  /* Composite data type, e.g. a table's row type */
2785  Form_pg_attribute att_tup;
2786 
2787  Assert(tupdesc);
2788  Assert(attnum <= tupdesc->natts);
2789  att_tup = TupleDescAttr(tupdesc, attnum - 1);
2790 
2791  /*
2792  * If dropped column, pretend it ain't there. See
2793  * notes in scanRTEForColumn.
2794  */
2795  if (att_tup->attisdropped)
2796  ereport(ERROR,
2797  (errcode(ERRCODE_UNDEFINED_COLUMN),
2798  errmsg("column \"%s\" of relation \"%s\" does not exist",
2799  NameStr(att_tup->attname),
2800  rte->eref->aliasname)));
2801  *vartype = att_tup->atttypid;
2802  *vartypmod = att_tup->atttypmod;
2803  *varcollid = att_tup->attcollation;
2804  }
2805  else if (functypclass == TYPEFUNC_SCALAR)
2806  {
2807  /* Base data type, i.e. scalar */
2808  *vartype = funcrettype;
2809  *vartypmod = -1;
2810  *varcollid = exprCollation(rtfunc->funcexpr);
2811  }
2812  else if (functypclass == TYPEFUNC_RECORD)
2813  {
2814  *vartype = list_nth_oid(rtfunc->funccoltypes,
2815  attnum - 1);
2816  *vartypmod = list_nth_int(rtfunc->funccoltypmods,
2817  attnum - 1);
2818  *varcollid = list_nth_oid(rtfunc->funccolcollations,
2819  attnum - 1);
2820  }
2821  else
2822  {
2823  /*
2824  * addRangeTableEntryForFunction should've caught
2825  * this
2826  */
2827  elog(ERROR, "function in FROM has unsupported return type");
2828  }
2829  return;
2830  }
2831  atts_done += rtfunc->funccolcount;
2832  }
2833 
2834  /* If we get here, must be looking for the ordinality column */
2835  if (rte->funcordinality && attnum == atts_done + 1)
2836  {
2837  *vartype = INT8OID;
2838  *vartypmod = -1;
2839  *varcollid = InvalidOid;
2840  return;
2841  }
2842 
2843  /* this probably can't happen ... */
2844  ereport(ERROR,
2845  (errcode(ERRCODE_UNDEFINED_COLUMN),
2846  errmsg("column %d of relation \"%s\" does not exist",
2847  attnum,
2848  rte->eref->aliasname)));
2849  }
2850  break;
2851  case RTE_JOIN:
2852  {
2853  /*
2854  * Join RTE --- get type info from join RTE's alias variable
2855  */
2856  Node *aliasvar;
2857 
2858  Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
2859  aliasvar = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
2860  Assert(aliasvar != NULL);
2861  *vartype = exprType(aliasvar);
2862  *vartypmod = exprTypmod(aliasvar);
2863  *varcollid = exprCollation(aliasvar);
2864  }
2865  break;
2866  case RTE_TABLEFUNC:
2867  case RTE_VALUES:
2868  case RTE_CTE:
2869  case RTE_NAMEDTUPLESTORE:
2870  {
2871  /*
2872  * tablefunc, VALUES, CTE, or ENR RTE --- get type info from
2873  * lists in the RTE
2874  */
2875  Assert(attnum > 0 && attnum <= list_length(rte->coltypes));
2876  *vartype = list_nth_oid(rte->coltypes, attnum - 1);
2877  *vartypmod = list_nth_int(rte->coltypmods, attnum - 1);
2878  *varcollid = list_nth_oid(rte->colcollations, attnum - 1);
2879 
2880  /* For ENR, better check for dropped column */
2881  if (!OidIsValid(*vartype))
2882  ereport(ERROR,
2883  (errcode(ERRCODE_UNDEFINED_COLUMN),
2884  errmsg("column %d of relation \"%s\" does not exist",
2885  attnum,
2886  rte->eref->aliasname)));
2887  }
2888  break;
2889  default:
2890  elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
2891  }
2892 }
Oid list_nth_oid(const List *list, int n)
Definition: list.c:432
List * joinaliasvars
Definition: parsenodes.h:995
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:276
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
List * coltypmods
Definition: parsenodes.h:1042
#define Int16GetDatum(X)
Definition: postgres.h:457
Definition: nodes.h:512
int errcode(int sqlerrcode)
Definition: elog.c:575
bool funcordinality
Definition: parsenodes.h:1006
unsigned int Oid
Definition: postgres_ext.h:31
TypeFuncClass get_expr_result_type(Node *expr, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:227
#define OidIsValid(objectId)
Definition: c.h:586
List * colcollations
Definition: parsenodes.h:1043
List * targetList
Definition: parsenodes.h:138
bool resjunk
Definition: primnodes.h:1382
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
void * list_nth(const List *list, int n)
Definition: list.c:410
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
TypeFuncClass
Definition: funcapi.h:155
#define ereport(elevel, rest)
Definition: elog.h:122
int list_nth_int(const List *list, int n)
Definition: list.c:421
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define InvalidOid
Definition: postgres_ext.h:36
List * funccoltypmods
Definition: parsenodes.h:1092
#define INT8OID
Definition: pg_type.h:304
List * funccolcollations
Definition: parsenodes.h:1093
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:680
#define lfirst(lc)
Definition: pg_list.h:106
char * aliasname
Definition: primnodes.h:42
List * functions
Definition: parsenodes.h:1005
Expr * expr
Definition: primnodes.h:1375
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
static int list_length(const List *l)
Definition: pg_list.h:89
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:720
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1123
RTEKind rtekind
Definition: parsenodes.h:951
Query * subquery
Definition: parsenodes.h:974
int errmsg(const char *fmt,...)
Definition: elog.c:797
TargetEntry * get_tle_by_resno(List *tlist, AttrNumber resno)
#define NameStr(name)
Definition: c.h:557
#define elog
Definition: elog.h:219
Alias * eref
Definition: parsenodes.h:1055
List * coltypes
Definition: parsenodes.h:1041
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1745

◆ get_tle_by_resno()