PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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

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

Function Documentation

RowMarkClause* get_parse_rowmark ( Query qry,
Index  rtindex 
)

Definition at line 3043 of file parse_relation.c.

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

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

3044 {
3045  ListCell *l;
3046 
3047  foreach(l, qry->rowMarks)
3048  {
3049  RowMarkClause *rc = (RowMarkClause *) lfirst(l);
3050 
3051  if (rc->rti == rtindex)
3052  return rc;
3053  }
3054  return NULL;
3055 }
List * rowMarks
Definition: parsenodes.h:161
#define lfirst(lc)
Definition: pg_list.h:106
bool get_rte_attribute_is_dropped ( RangeTblEntry rte,
AttrNumber  attnum 
)

Definition at line 2885 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_type(), 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(), TupleDescAttr, and TYPEFUNC_COMPOSITE.

Referenced by AcquireRewriteLocks().

2886 {
2887  bool result;
2888 
2889  switch (rte->rtekind)
2890  {
2891  case RTE_RELATION:
2892  {
2893  /*
2894  * Plain relation RTE --- get the attribute's catalog entry
2895  */
2896  HeapTuple tp;
2897  Form_pg_attribute att_tup;
2898 
2899  tp = SearchSysCache2(ATTNUM,
2900  ObjectIdGetDatum(rte->relid),
2901  Int16GetDatum(attnum));
2902  if (!HeapTupleIsValid(tp)) /* shouldn't happen */
2903  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
2904  attnum, rte->relid);
2905  att_tup = (Form_pg_attribute) GETSTRUCT(tp);
2906  result = att_tup->attisdropped;
2907  ReleaseSysCache(tp);
2908  }
2909  break;
2910  case RTE_SUBQUERY:
2911  case RTE_TABLEFUNC:
2912  case RTE_VALUES:
2913  case RTE_CTE:
2914 
2915  /*
2916  * Subselect, Table Functions, Values, CTE RTEs never have dropped
2917  * columns
2918  */
2919  result = false;
2920  break;
2921  case RTE_NAMEDTUPLESTORE:
2922  {
2923  /* Check dropped-ness by testing for valid coltype */
2924  if (attnum <= 0 ||
2925  attnum > list_length(rte->coltypes))
2926  elog(ERROR, "invalid varattno %d", attnum);
2927  result = !OidIsValid((list_nth_oid(rte->coltypes, attnum - 1)));
2928  }
2929  break;
2930  case RTE_JOIN:
2931  {
2932  /*
2933  * A join RTE would not have dropped columns when constructed,
2934  * but one in a stored rule might contain columns that were
2935  * dropped from the underlying tables, if said columns are
2936  * nowhere explicitly referenced in the rule. This will be
2937  * signaled to us by a null pointer in the joinaliasvars list.
2938  */
2939  Var *aliasvar;
2940 
2941  if (attnum <= 0 ||
2942  attnum > list_length(rte->joinaliasvars))
2943  elog(ERROR, "invalid varattno %d", attnum);
2944  aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
2945 
2946  result = (aliasvar == NULL);
2947  }
2948  break;
2949  case RTE_FUNCTION:
2950  {
2951  /* Function RTE */
2952  ListCell *lc;
2953  int atts_done = 0;
2954 
2955  /*
2956  * Dropped attributes are only possible with functions that
2957  * return named composite types. In such a case we have to
2958  * look up the result type to see if it currently has this
2959  * column dropped. So first, loop over the funcs until we
2960  * find the one that covers the requested column.
2961  */
2962  foreach(lc, rte->functions)
2963  {
2964  RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
2965 
2966  if (attnum > atts_done &&
2967  attnum <= atts_done + rtfunc->funccolcount)
2968  {
2969  TypeFuncClass functypclass;
2970  Oid funcrettype;
2971  TupleDesc tupdesc;
2972 
2973  functypclass = get_expr_result_type(rtfunc->funcexpr,
2974  &funcrettype,
2975  &tupdesc);
2976  if (functypclass == TYPEFUNC_COMPOSITE)
2977  {
2978  /* Composite data type, e.g. a table's row type */
2979  Form_pg_attribute att_tup;
2980 
2981  Assert(tupdesc);
2982  Assert(attnum - atts_done <= tupdesc->natts);
2983  att_tup = TupleDescAttr(tupdesc,
2984  attnum - atts_done - 1);
2985  return att_tup->attisdropped;
2986  }
2987  /* Otherwise, it can't have any dropped columns */
2988  return false;
2989  }
2990  atts_done += rtfunc->funccolcount;
2991  }
2992 
2993  /* If we get here, must be looking for the ordinality column */
2994  if (rte->funcordinality && attnum == atts_done + 1)
2995  return false;
2996 
2997  /* this probably can't happen ... */
2998  ereport(ERROR,
2999  (errcode(ERRCODE_UNDEFINED_COLUMN),
3000  errmsg("column %d of relation \"%s\" does not exist",
3001  attnum,
3002  rte->eref->aliasname)));
3003  result = false; /* keep compiler quiet */
3004  }
3005  break;
3006  default:
3007  elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
3008  result = false; /* keep compiler quiet */
3009  }
3010 
3011  return result;
3012 }
Oid list_nth_oid(const List *list, int n)
Definition: list.c:432
List * joinaliasvars
Definition: parsenodes.h:989
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:84
#define Int16GetDatum(X)
Definition: postgres.h:457
int errcode(int sqlerrcode)
Definition: elog.c:575
bool funcordinality
Definition: parsenodes.h:1000
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:163
TypeFuncClass get_expr_result_type(Node *expr, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:227
#define OidIsValid(objectId)
Definition: c.h:532
#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:150
#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:681
#define lfirst(lc)
Definition: pg_list.h:106
char * aliasname
Definition: primnodes.h:42
List * functions
Definition: parsenodes.h:999
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:945
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
Alias * eref
Definition: parsenodes.h:1049
List * coltypes
Definition: parsenodes.h:1035
char* get_rte_attribute_name ( RangeTblEntry rte,
AttrNumber  attnum 
)

Definition at line 2658 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().

2659 {
2660  if (attnum == InvalidAttrNumber)
2661  return "*";
2662 
2663  /*
2664  * If there is a user-written column alias, use it.
2665  */
2666  if (rte->alias &&
2667  attnum > 0 && attnum <= list_length(rte->alias->colnames))
2668  return strVal(list_nth(rte->alias->colnames, attnum - 1));
2669 
2670  /*
2671  * If the RTE is a relation, go to the system catalogs not the
2672  * eref->colnames list. This is a little slower but it will give the
2673  * right answer if the column has been renamed since the eref list was
2674  * built (which can easily happen for rules).
2675  */
2676  if (rte->rtekind == RTE_RELATION)
2677  return get_relid_attribute_name(rte->relid, attnum);
2678 
2679  /*
2680  * Otherwise use the column name from eref. There should always be one.
2681  */
2682  if (attnum > 0 && attnum <= list_length(rte->eref->colnames))
2683  return strVal(list_nth(rte->eref->colnames, attnum - 1));
2684 
2685  /* else caller gave us a bogus attnum */
2686  elog(ERROR, "invalid attnum %d for rangetable entry %s",
2687  attnum, rte->eref->aliasname);
2688  return NULL; /* keep compiler quiet */
2689 }
Alias * alias
Definition: parsenodes.h:1048
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:945
#define elog
Definition: elog.h:219
Alias * eref
Definition: parsenodes.h:1049
void get_rte_attribute_type ( RangeTblEntry rte,
AttrNumber  attnum,
Oid vartype,
int32 vartypmod,
Oid varcollid 
)

Definition at line 2696 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_RECORD, and TYPEFUNC_SCALAR.

Referenced by make_var().

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