catquery.h 5.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
/*-------------------------------------------------------------------------
 *
 * catquery.h
 *	  catalog query
 *
 *
 * Copyright (c) 2011, 2012 Greenplum inc
 *
 *-------------------------------------------------------------------------
 */
#ifndef CATQUERY_H
#define CATQUERY_H

#include "access/genam.h"
#include "access/relscan.h"
#include "access/sdir.h"
#include "catalog/catcore.h"
#include "nodes/primnodes.h"
#include "storage/lock.h"
#include "utils/catcache.h"
#include "utils/relcache.h"

/*
 * TODO: probably "hash cookie" is meaningless now.  More like parser state.
 */
typedef struct caql_hash_cookie
{
	const char *name;		/* caql string */
	int			basequery_code; /* corresponding base query */
	int			bUpdate;	/* SELECT ... FOR UPDATE */
	int			bInsert;	/* INSERT INTO  */
	bool		bAllEqual;	/* true if all equality operators */
	AttrNumber	attnum;		/* column number (or 0 if no column specified) */
	Oid			atttype;		/* type OID of the specified column */
	const CatCoreRelation *relation; /* target relation */
	const CatCoreIndex    *index; /* available index */
	int			syscacheid;	/* syscache matching the index (-1 if none) */
	Node	   *query;		/* parsed syntax tree */

	/* debug info */
	char	   *file;		/* file location */
	int			lineno;		/* line number */
} caql_hash_cookie;

typedef struct cqListData
{
	bool		bGood;			/* if true, struct is allocated */
	const char* caqlStr;		/* caql string */
	int			numkeys;
	int			maxkeys;
	const char* filename;		/* FILE and LINE macros */
	int			lineno;
	Datum		cqlKeys[5];		/* key array */
} cq_list;

typedef struct cqContextData
{
	int			cq_basequery_code; /* corresponding base query */
	int			cq_uniqquery_code; /* unique query number */
	bool		cq_free;		/* if true, free this ctx at endscan */
	bool		cq_freeScan;	/* if true, free scan at endscan */
	Oid			cq_relationId;	/* relation id */
	Relation	cq_heap_rel;	/* catalog being scanned */
	TupleDesc	cq_tupdesc;		/* tuple descriptor */
	SysScanDesc cq_sysScan;		/* heap or index scan */		
	bool		cq_externrel;	/* heap rel external to caql */
	bool		cq_setsnapshot;	/* use cq_snapshot (else default) */
	Snapshot	cq_snapshot;	/* snapshot to see */
	LOCKMODE	cq_lockmode;	/* locking mode */
	bool		cq_EOF;			/* true if hit end of fetch */

	bool		cq_useidxOK;	/* use supplied indexOK mode) */

	bool		cq_pklock_excl;	/* lock exclusive if true */

	Datum		cq_datumKeys[5];/* key array of datums */
	int			cq_NumKeys;		/* number of keys */
	ScanKeyData	cq_scanKeys[5]; /* initialized sysscan key (from datums) */

	const CatCoreRelation *relation; /* relation being read */
	const CatCoreIndex *index;	/* usable index on the relation */

	/* 	index update information */
	CatalogIndexState	cq_indstate;	/* non-NULL after CatalogOpenIndexes */
	bool				cq_bScanBlock;	/* true if ctx in
										 * beginscan/endscan block */
		
	/* 	these attributes control syscache vs normal heap/index
89
	 * 	scan. If usesyscache is set, then sysScan is NULL, and cq_cacheId is the
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
	 * 	SysCacheIdentifier.
	 */
	bool		cq_usesyscache;	/* use syscache (internal) */
	int			cq_cacheId; 	/* cache identifier */
	Datum	   *cq_cacheKeys;	/* array of keys */
	HeapTuple   cq_lasttup;		/* last tuple fetched (for ReleaseSysCache) */

} cqContext;

/* return the first tuple 
   (and set a flag if the scan finds a second match) 
*/
HeapTuple	 caql_getfirst_only(cqContext *pCtx, 
								bool *pbOnly,
								cq_list *pcql);
#define		 caql_getfirst(pCtx, pcql) caql_getfirst_only(pCtx, NULL, pcql)

/* return the specified oid column of the first tuple 
   (and set a flag if the scan finds a second match) 
*/
Oid			 caql_getoid_only(cqContext *pCtx, 
							  bool *pbOnly,
							  cq_list *pcql);
Oid			 caql_getoid_plus(cqContext *pCtx0, int *pFetchcount,
							  bool *pbIsNull, cq_list *pcql);
#define		 caql_getoid(pCtx, pcql) caql_getoid_plus(pCtx, NULL, NULL, pcql)

cqContext	*caql_beginscan(cqContext *pCtx, cq_list *pcql);
HeapTuple	 caql_getnext(cqContext *pCtx);
/* XXX XXX: endscan must specify if hold or release locks */
void		 caql_endscan(cqContext *pCtx);

/* retrieve the last (current) tuple */
#define caql_get_current(pCtx) ((pCtx)->cq_lasttup)

/* 
   NOTE: don't confuse caql_getattr and caql_getattname.  

   caql_getattr extracts the specified column (by attnum) from the
   current tuple in the pcqCtx.

   caql_getattname fetches a copy of tuple from pg_attribute that
   _describes_ a column of a table. (should really be get_by_attname)

 */

/* equivalent of SysCacheGetAttr - extract a specific attribute for
 *  current tuple 
 */
Datum caql_getattr(cqContext *pCtx, AttrNumber attnum, bool *isnull);

/* return the specified Name or Text column of the first tuple 
   (and set the fetchcount or isnull if specified)
*/
char		*caql_getcstring_plus(cqContext *pCtx0, int *pFetchcount,
								  bool *pbIsNull, cq_list *pcql);
#define		 caql_getcstring(pCtx, pcql) \
		caql_getcstring_plus(pCtx, NULL, NULL, pcql)

cq_list *cql1(const char* caqlStr, const char* filename, int lineno, ...);

/* caql context modification functions 
 *
 * cqclr and caql_addrel() are ok, but the others are generally used
 * to support legacy code requirements, and may be deprecated in
 * future releases
 */
cqContext	*caql_addrel(cqContext *pCtx, Relation rel);		/*  */
cqContext	*caql_snapshot(cqContext *pCtx, Snapshot ss);		/*  */

cqContext	*cqclr(cqContext	 *pCtx);						/*  */
#define	cqClearContext(pcqContext) MemSet(pcqContext, 0, sizeof(cqContext))

void caql_logquery(const char *funcname, const char *filename, int lineno,
			  int uniqquery_code, Oid arg1);

/* ifdef gnuc ! */
#define cql(x, ...) cql1(x, __FILE__, __LINE__, __VA_ARGS__)

/* MPP-18975: wrapper to assuage type checker (only CString currently). 
   See calico.pl/check_datum_type() for details.
 */
#define cqlIsDatumForCString(d) (d)

/* caqlanalyze.c */
struct caql_hash_cookie * cq_lookup(const char *str, unsigned int len, cq_list *pcql);
cqContext *caql_switch(struct caql_hash_cookie *pchn, cqContext *pCtx, cq_list *pcql);


#endif   /* CATQUERY_H */