blob: fbfc842d5c6a927707c5edefaef0f5d82eb9ad12 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*-------------------------------------------------------------------------
*
* catquery.h
* catalog query
*
*-------------------------------------------------------------------------
*/
#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 bDelete; /* query performs DELETE */
int bCount; /* SELECT COUNT(*) (or DELETE) */
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) */
const CatCoreRelation *relation; /* target relation */
const CatCoreIndex *index; /* available index */
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 */
bool cq_setlockmode; /* use cq_lockmode (else default) */
LOCKMODE cq_lockmode; /* locking mode */
bool cq_EOF; /* true if hit end of fetch */
bool cq_setidxOK; /* set the indexOK mode */
bool cq_useidxOK; /* use supplied indexOK mode) */
bool cq_setpklock; /* lock primary keys on fetch if set */
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
* scan. If setsyscache is set, then usesyscache is the
* user-setting, else catquery chooses. If usesyscache is set
* then sysScan is NULL, and cq_cacheId is the
* SysCacheIdentifier.
*/
bool cq_setsyscache; /* use syscache (else heap/index scan) */
bool cq_usesyscache; /* use syscache (internal) */
bool cq_bCacheList; /* cache list search (internal) */
int cq_cacheId; /* cache identifier */
Datum *cq_cacheKeys; /* array of keys */
HeapTuple cq_lasttup; /* last tuple fetched (for ReleaseSysCache) */
} cqContext;
/* internal use */
bool is_builtin_object(cqContext *pCtx, HeapTuple tuple);
Datum caql_getattr_internal(cqContext *pCtx, HeapTuple tup,
AttrNumber attnum, bool *isnull);
void caql_heapclose(cqContext *pCtx);
void disable_catalog_check(cqContext *pCtx, HeapTuple tuple);
/* count (and optionally delete) */
int caql_getcount(cqContext *pCtx, cq_list *pcql);
/* 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);
HeapTuple caql_getprev(cqContext *pCtx);
/* XXX XXX: endscan must specify if hold or release locks */
void caql_endscan(cqContext *pCtx);
/* list-search interface. Users of this must import catcache.h too */
extern struct catclist *caql_begin_CacheList(cqContext *pCtx,
cq_list *pcql);
#define caql_end_CacheList(x) ReleaseSysCacheList(x)
/* during beginscan/endscan iteration,
* or subsequent to a getfirst (where a context was supplied),
* delete, update or modify the current tuple
*/
/* delete current tuple */
void caql_delete_current(cqContext *pCtx);
/* insert tuple */
Oid caql_insert(cqContext *pCtx, HeapTuple tup);
/* insert tuple to in memory only */
void caql_insert_inmem(cqContext *pCtx, HeapTuple tup);
/* update current tuple */
void caql_update_current(cqContext *pCtx, HeapTuple tup);
/* modify current tuple */
HeapTuple caql_modify_current(cqContext *pCtx, Datum *replValues,
bool *replIsnull,
bool *doReplace);
/* form tuple */
HeapTuple caql_form_tuple(cqContext *pCtx, Datum *replValues,
bool *replIsnull);
/* 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);
/* equivalent of SearchSysCacheCopyAttName - return copy of the tuple
* describing a column of a table
*/
HeapTuple caql_getattname(cqContext *pCtx, Oid relid, const char *attname);
/* same as SearchSysCacheAttName - return a scan where the tuple is
* *already* fetched, so use caql_get_current (not getnext!) to get
* the tuple, and endscan to free the context
*/
cqContext *caql_getattname_scan(cqContext *pCtx,
Oid relid, const char *attname);
/*
* adapted from original lsyscache.c/get_attnum()
*
* Given the relation id and the attribute name,
* return the "attnum" field from the attribute relation.
*
* Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
*/
AttrNumber caql_getattnumber(Oid relid, const char *attname);
/* 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_indexOK(cqContext *pCtx, bool bindexOK); /* */
cqContext *caql_lockmode(cqContext *pCtx, LOCKMODE lm); /* */
cqContext *caql_PKLOCK(cqContext *pCtx, bool bExclusive); /* */
cqContext *caql_snapshot(cqContext *pCtx, Snapshot ss); /* */
cqContext *caql_syscache(cqContext *pCtx, bool bUseCache); /* */
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);
/* CAQL prototype: expand to nothing */
#define cql0(x, ...) if (0) {} else
/* 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 */