示例#1
0
/* ----------------------------------------------------------------
 * caql_insert_inmem()
 * during beginscan/endscan iteration, insert a tuple to in-memory-only relation
 * ----------------------------------------------------------------
 */
void
caql_insert_inmem(cqContext *pCtx, HeapTuple tup)
{
	InMemHeapRelation inmemrel = NULL;
	Relation rel = pCtx->cq_heap_rel;

	Assert(RelationIsValid(rel));

	disable_catalog_check(pCtx, tup);

	{ /* scope for caql_iud_switch */
		caql_iud_switch(pCtx, 1, NULL, tup, true /* dontWait */);

		inmemrel = OidGetInMemHeapRelation(rel->rd_id, INMEM_ONLY_MAPPING);
		if (NULL == inmemrel)
		{
			inmemrel = InMemHeap_Create(rel->rd_id, rel, FALSE /* ownRel */, 10 /* initSize */, pCtx->cq_lockmode /*AccessShareLock*/,
					RelationGetRelationName(rel), FALSE /* createIndex */, 0 /* keyAttrno */, INMEM_ONLY_MAPPING);
			elog(DEBUG2, "Created new entry for in memory table %s", RelationGetRelationName(rel));
		}
		Assert(NULL != inmemrel);
		InMemHeap_CheckConstraints(inmemrel, tup);
		InMemHeap_Insert(inmemrel, tup, -1 /* valid for all segments */);

		// TODO: is it relevant for in-memory?
		/* keep the catalog indexes up to date (if has any) */
		//caql_UpdateIndexes(pCtx, rel, tup);
	}
}
示例#2
0
文件: catquery.c 项目: 454135329/gpdb
/* ----------------------------------------------------------------
 * caql_getprev()
 * NOTE: similar to caql_getnext(), but backwards.  
 * Usage is rare and potentially dangerous.  
 * The scankey should be set to point to the *last* key, not the 
 * first, typically using COLNAME <= BINDVALUE, but this assumes
 * a unique index.  (with a non-unique index the beginscan could
 * potentially position at the *start* of a group of duplicates,
 * not the end)
 * ----------------------------------------------------------------
 */
HeapTuple caql_getprev(cqContext *pCtx)
{
	HeapTuple tuple;
	/* set EOF when get invalid tuple */

	if (pCtx->cq_EOF)
		return (NULL);

	if (!pCtx->cq_usesyscache)
	{
		tuple = systable_getprev(pCtx->cq_sysScan); 
		pCtx->cq_EOF = !(HeapTupleIsValid(tuple));
	}
	else
	{
		Insist(0); /* XXX XXX: illegal ? */
		/* syscache is always 0 or 1 entry */
		tuple = SearchSysCacheKeyArray(pCtx->cq_cacheId, 
									   pCtx->cq_NumKeys, 
									   pCtx->cq_cacheKeys);
		
		pCtx->cq_EOF	 = true;  /* at EOF always, because only 0 or 1 */
	}

	disable_catalog_check(pCtx, tuple);

	pCtx->cq_lasttup = tuple; /* need this for ReleaseSysCache */

	return (tuple);
}
示例#3
0
/* ----------------------------------------------------------------
 * caql_getnext()
 * Return a tuple.  The tuple is only valid until caql_endscan(),
 * or until the next call of caql_getnext().
 * NOTE: this function will return NULL when no tuples remain to
 * satisfy the caql predicate -- use HeapTupleIsValid() to detect
 * this condition.
 * ----------------------------------------------------------------
 */
HeapTuple
caql_getnext(cqContext *pCtx)
{
	HeapTuple tuple;
	/* set EOF when get invalid tuple */

	if (pCtx->cq_EOF)
		return (NULL);

	if (!pCtx->cq_usesyscache)
	{
		tuple = systable_getnext(pCtx->cq_sysScan);
		pCtx->cq_EOF = !(HeapTupleIsValid(tuple));
	}
	else
	{
		/* syscache is always 0 or 1 entry */
		tuple = SearchSysCacheKeyArray(pCtx->cq_cacheId,
									   pCtx->cq_NumKeys,
									   pCtx->cq_cacheKeys);

		pCtx->cq_EOF	 = true;  /* at EOF always, because only 0 or 1 */
	}

	disable_catalog_check(pCtx, tuple);

	if (pCtx->cq_setpklock)
		caql_iud_switch(pCtx, 0, tuple, NULL, false /* Wait */);

	pCtx->cq_lasttup = tuple; /* need this for ReleaseSysCache */

	return tuple;
}
示例#4
0
文件: catquery.c 项目: 454135329/gpdb
/* ----------------------------------------------------------------
 * caql_delete_current()
 * during beginscan/endscan iteration, delete current tuple 
 * ----------------------------------------------------------------
 */
void caql_delete_current(cqContext *pCtx)
{
	Relation				 rel;

	rel  = pCtx->cq_heap_rel;
	Assert(RelationIsValid(rel));

	disable_catalog_check(pCtx, pCtx->cq_lasttup);
	if (HeapTupleIsValid(pCtx->cq_lasttup))
		simple_heap_delete(rel, &(pCtx->cq_lasttup)->t_self);
}
示例#5
0
/* ----------------------------------------------------------------
 * caql_delete_current()
 * during beginscan/endscan iteration, delete current tuple
 * ----------------------------------------------------------------
 */
void
caql_delete_current(cqContext *pCtx)
{
	Relation				 rel;

	rel  = pCtx->cq_heap_rel;
	Assert(RelationIsValid(rel));

	disable_catalog_check(pCtx, pCtx->cq_lasttup);
	if (HeapTupleIsValid(pCtx->cq_lasttup))
	{
		caql_iud_switch(pCtx, 0, pCtx->cq_lasttup, NULL, true /* dontWait */);
		simple_heap_delete(rel, &(pCtx->cq_lasttup)->t_self);
	}
}
示例#6
0
文件: catquery.c 项目: 454135329/gpdb
/* ----------------------------------------------------------------
 * caql_update_current()
 * during beginscan/endscan iteration, update current tuple,
 * and update catalog indexes if necessary 
 * NOTE: a separate call to CatalogUpdateIndexes after this will 
 * cause an error
 * ----------------------------------------------------------------
 */
void caql_update_current(cqContext *pCtx, HeapTuple tup)
{
	Relation				 rel;

	rel  = pCtx->cq_heap_rel;
	Assert(RelationIsValid(rel));

	Insist(HeapTupleIsValid(pCtx->cq_lasttup));

	disable_catalog_check(pCtx, pCtx->cq_lasttup);

	simple_heap_update(rel, &(pCtx->cq_lasttup)->t_self, tup);

	/* keep the catalog indexes up to date (if has any) */
	caql_UpdateIndexes(pCtx, rel, tup);
}
示例#7
0
文件: catquery.c 项目: 454135329/gpdb
/* ----------------------------------------------------------------
 * caql_insert()
 * during beginscan/endscan iteration, insert a tuple
 * NOTE: a separate call to CatalogUpdateIndexes after this will 
 * cause an error
 * ----------------------------------------------------------------
 */
Oid caql_insert(cqContext *pCtx, HeapTuple tup)
{
	Relation		 rel;
	Oid				 result;

	rel  = pCtx->cq_heap_rel;
	Assert(RelationIsValid(rel));

	disable_catalog_check(pCtx, tup);

	result = simple_heap_insert(rel, tup);

	/* keep the catalog indexes up to date (if has any) */
	caql_UpdateIndexes(pCtx, rel, tup);

	return (result);
}
示例#8
0
文件: catquery.c 项目: 454135329/gpdb
/* ----------------------------------------------------------------
 * caql_getfirst_only()
 * Return a copy the first tuple, pallocd in the current memory context,
 * and end the scan.  Clients should heap_freetuple() as necessary.
 * If pbOnly is not NULL, return TRUE if a second tuple is not found,
 * else return FALSE
 * NOTE: this function will return NULL if no tuples satisfy the
 * caql predicate -- use HeapTupleIsValid() to detect this condition.
 * ----------------------------------------------------------------
 */
HeapTuple caql_getfirst_only(cqContext *pCtx0, bool *pbOnly, cq_list *pcql)
{
	const char*				 caql_str = pcql->caqlStr;
	const char*				 filenam  = pcql->filename;
	int						 lineno	  = pcql->lineno;
	struct caql_hash_cookie	*pchn	  = cq_lookup(caql_str, strlen(caql_str), pcql);
	cqContext				*pCtx;
	cqContext				 cqc;
	HeapTuple				 tuple, newTup = NULL;

	if (NULL == pchn)
		elog(ERROR, "invalid caql string: %s\nfile: %s, line %d", 
			 caql_str, filenam, lineno);

	Assert(!pchn->bInsert); /* INSERT not allowed */

	/* use the provided context, or provide a clean local ctx  */
	if (pCtx0)
		pCtx = pCtx0;
	else
		pCtx = cqclr(&cqc);

	pCtx = caql_switch(pchn, pCtx, pcql);
	/* NOTE: caql_switch frees the pcql */

	if (pbOnly) *pbOnly = true;

	/* use the SysCache */
	if (pCtx->cq_usesyscache)
	{
		tuple = SearchSysCacheKeyArray(pCtx->cq_cacheId, 
									   pCtx->cq_NumKeys, 
									   pCtx->cq_cacheKeys);

		disable_catalog_check(pCtx, tuple);
		if (HeapTupleIsValid(tuple))
		{
			newTup = heap_copytuple(tuple);
			ReleaseSysCache(tuple);
			/* only one */
		}
		caql_heapclose(pCtx);

		pCtx->cq_lasttup = newTup; /* need this for update/delete */

		return (newTup);
	}

	if (HeapTupleIsValid(tuple = systable_getnext(pCtx->cq_sysScan)))
	{
		disable_catalog_check(pCtx, tuple);

		/* always copy the tuple, because the endscan releases tup memory */
		newTup = heap_copytuple(tuple);
 
		if (pbOnly)
		{
			*pbOnly = 
				!(HeapTupleIsValid(systable_getnext(pCtx->cq_sysScan)));
		}
	}
	systable_endscan(pCtx->cq_sysScan); 
	caql_heapclose(pCtx);

	pCtx->cq_lasttup = newTup; /* need this for update/delete */
	return (newTup);
}
示例#9
0
文件: catquery.c 项目: 454135329/gpdb
/* ----------------------------------------------------------------
 * caql_getcount()
 * Perform COUNT(*) or DELETE
 * ----------------------------------------------------------------
 */
int caql_getcount(cqContext *pCtx0, cq_list *pcql)
{
	const char*				 caql_str = pcql->caqlStr;
	const char*				 filenam  = pcql->filename;
	int						 lineno	  = pcql->lineno;
	struct caql_hash_cookie	*pchn	  = cq_lookup(caql_str, strlen(caql_str), pcql);
	cqContext				*pCtx;
	cqContext				 cqc;
	HeapTuple				 tuple;
	Relation				 rel;
	int						 ii		  = 0;

	if (NULL == pchn)
		elog(ERROR, "invalid caql string: %s\nfile: %s, line %d", 
			 caql_str, filenam, lineno);

	Assert(!pchn->bInsert); /* INSERT not allowed */

	/* use the provided context, or provide a clean local ctx  */
	if (pCtx0)
		pCtx = pCtx0;
	else
		pCtx = cqclr(&cqc);

	pCtx = caql_switch(pchn, pCtx, pcql);
	/* NOTE: caql_switch frees the pcql */
	rel  = pCtx->cq_heap_rel;

	/* use the SysCache */
	if (pCtx->cq_usesyscache)
	{
		tuple = SearchSysCacheKeyArray(pCtx->cq_cacheId, 
									   pCtx->cq_NumKeys, 
									   pCtx->cq_cacheKeys);

		disable_catalog_check(pCtx, tuple);
		if (HeapTupleIsValid(tuple))
		{
			ii++;
			pCtx->cq_lasttup = tuple;
			if (pchn->bDelete)
				simple_heap_delete(rel, &tuple->t_self);

			ReleaseSysCache(tuple);
			/* only one */
		}
		caql_heapclose(pCtx);
		return (ii);
	}

	while (HeapTupleIsValid(tuple = systable_getnext(pCtx->cq_sysScan)))
	{
		disable_catalog_check(pCtx, tuple);
		if (HeapTupleIsValid(tuple) && pchn->bDelete)
		{
			pCtx->cq_lasttup = tuple;
			if (pchn->bDelete)
				simple_heap_delete(rel, &tuple->t_self);
		}

		ii++;
	}
	systable_endscan(pCtx->cq_sysScan); 
	caql_heapclose(pCtx);

	return (ii);
}
示例#10
0
文件: catquery.c 项目: 454135329/gpdb
/* ----------------------------------------------------------------
 * caql_getcstring_plus()
 * Return a cstring column from the first tuple and end the scan.
 * ----------------------------------------------------------------
 */
char *caql_getcstring_plus(cqContext *pCtx0, int *pFetchcount,
						   bool *pbIsNull, cq_list *pcql)
{
	const char *caql_str = pcql->caqlStr;
	const char *filenam = pcql->filename;
	int			lineno = pcql->lineno;
	struct caql_hash_cookie	*pchn = cq_lookup(caql_str, strlen(caql_str), pcql);
	cqContext  *pCtx;
	cqContext   cqc;
	HeapTuple   tuple;
	char	   *result = NULL;

	if (NULL == pchn)
		elog(ERROR, "invalid caql string: %s\nfile: %s, line %d", 
			 caql_str, filenam, lineno);

	Assert(!pchn->bInsert); /* INSERT not allowed */

	/* use the provided context, or provide a clean local ctx  */
	if (pCtx0)
		pCtx = pCtx0;
	else
		pCtx = cqclr(&cqc);

	pCtx = caql_switch(pchn, pCtx, pcql);
	/* NOTE: caql_switch frees the pcql */

	if (pFetchcount)
		*pFetchcount = 0;
	if (pbIsNull)
		*pbIsNull = true;

	/* use the SysCache */
	if (pCtx->cq_usesyscache)
	{
		tuple = SearchSysCacheKeyArray(pCtx->cq_cacheId, 
									   pCtx->cq_NumKeys, 
									   pCtx->cq_cacheKeys);
	}
	else
	{
		tuple = systable_getnext(pCtx->cq_sysScan);
	}

	disable_catalog_check(pCtx, tuple);

	if (HeapTupleIsValid(tuple))
	{
		bool		isnull;
		Datum		d;

		if (pFetchcount)
			*pFetchcount = 1;

		d = caql_getattr_internal(pCtx, tuple, pchn->attnum, &isnull);

		if (!isnull)
		{
			switch (pchn->atttype)
			{
				case NAMEOID:
					result = DatumGetCString(DirectFunctionCall1(nameout, d));
					break;

				case TEXTOID:
					result = DatumGetCString(DirectFunctionCall1(textout, d));
					break;

				default:
					elog(ERROR, "column not a cstring: %s\nfile: %s, line %d", 
						 caql_str, filenam, lineno);
			}
		}
		if (pbIsNull)
			*pbIsNull = isnull;
	} /* end HeapTupleIsValid */

	if (pCtx->cq_usesyscache)
	{  
		if (HeapTupleIsValid(tuple))
			ReleaseSysCache(tuple);
	}
	else
	{	
		if (pFetchcount && HeapTupleIsValid(tuple))
		{				
			if (HeapTupleIsValid(systable_getnext(pCtx->cq_sysScan)))
			{
				*pFetchcount = 2;	
			}
		}
		systable_endscan(pCtx->cq_sysScan); 
	}		
	caql_heapclose(pCtx);

	return (result);
} /* end caql_getcstring_plus */
示例#11
0
文件: catquery.c 项目: 454135329/gpdb
/* ----------------------------------------------------------------
 * caql_getoid_only()
 * Return the oid of the first tuple and end the scan
 * If pbOnly is not NULL, return TRUE if a second tuple is not found,
 * else return FALSE
 * ----------------------------------------------------------------
 */
Oid caql_getoid_only(cqContext *pCtx0, bool *pbOnly, cq_list *pcql)
{
	const char *caql_str = pcql->caqlStr;
	const char *filenam = pcql->filename;
	int			lineno = pcql->lineno;
	struct caql_hash_cookie	*pchn = cq_lookup(caql_str, strlen(caql_str), pcql);
	cqContext  *pCtx;
	cqContext	cqc;
	HeapTuple	tuple;
	Oid			result = InvalidOid;

	if (NULL == pchn)
		elog(ERROR, "invalid caql string: %s\nfile: %s, line %d", 
			 caql_str, filenam, lineno);

	Assert(!pchn->bInsert); /* INSERT not allowed */

	/* use the provided context, or provide a clean local ctx  */
	if (pCtx0)
		pCtx = pCtx0;
	else
		pCtx = cqclr(&cqc);

	pCtx = caql_switch(pchn, pCtx, pcql);
	/* NOTE: caql_switch frees the pcql */

	if (pbOnly)
		*pbOnly = true;

	/* use the SysCache */
	if (pCtx->cq_usesyscache)
	{
		tuple = SearchSysCacheKeyArray(pCtx->cq_cacheId, 
									   pCtx->cq_NumKeys, 
									   pCtx->cq_cacheKeys);

		disable_catalog_check(pCtx, tuple);

		if (HeapTupleIsValid(tuple))
		{
			result = HeapTupleGetOid(tuple);
			ReleaseSysCache(tuple);
			/* only one */
		}
		caql_heapclose(pCtx);

		return (result);
	}

	if (HeapTupleIsValid(tuple = systable_getnext(pCtx->cq_sysScan)))
	{
		disable_catalog_check(pCtx, tuple);

		result = HeapTupleGetOid(tuple);

		if (pbOnly)
		{
			*pbOnly = 
				!(HeapTupleIsValid(tuple = 
								   systable_getnext(pCtx->cq_sysScan)));
		}
	}
	systable_endscan(pCtx->cq_sysScan); 
	caql_heapclose(pCtx);
	return (result);
}
示例#12
0
文件: catquery.c 项目: 454135329/gpdb
/* ----------------------------------------------------------------
 * caql_getoid_plus()
 * Return an oid column from the first tuple and end the scan.
 * Note: this works for regproc columns as well, but you should cast
 * the output as RegProcedure.
 * ----------------------------------------------------------------
 */
Oid caql_getoid_plus(cqContext *pCtx0, int *pFetchcount,
					 bool *pbIsNull, cq_list *pcql)
{
	const char *caql_str = pcql->caqlStr;
	const char *filenam = pcql->filename;
	int			lineno = pcql->lineno;
	struct caql_hash_cookie	*pchn = cq_lookup(caql_str, strlen(caql_str), pcql);
	cqContext  *pCtx;
	cqContext	cqc;
	HeapTuple	tuple;
	Oid			result = InvalidOid;

	if (NULL == pchn)
		elog(ERROR, "invalid caql string: %s\nfile: %s, line %d", 
			 caql_str, filenam, lineno);

	Assert(!pchn->bInsert); /* INSERT not allowed */

	/* use the provided context, or provide a clean local ctx  */
	if (pCtx0)
		pCtx = pCtx0;
	else
		pCtx = cqclr(&cqc);

	pCtx = caql_switch(pchn, pCtx, pcql);
	/* NOTE: caql_switch frees the pcql */

	if (pFetchcount)
		*pFetchcount = 0;
	if (pbIsNull)
		*pbIsNull = true;

	/* use the SysCache */
	if (pCtx->cq_usesyscache)
	{
		tuple = SearchSysCacheKeyArray(pCtx->cq_cacheId, 
									   pCtx->cq_NumKeys, 
									   pCtx->cq_cacheKeys);
	}
	else
	{
		tuple = systable_getnext(pCtx->cq_sysScan);
	}

	disable_catalog_check(pCtx, tuple);
	if (HeapTupleIsValid(tuple))
	{
		if (pFetchcount)
			*pFetchcount = 1;
		
		/* if attnum not set, (InvalidAttrNumber == 0)
		 * use tuple oid, else extract oid from column 
		 * (includes ObjectIdAttributeNumber == -2) 
		 */
		if (pchn->attnum <= InvalidAttrNumber) 
		{
			if (pbIsNull)
				*pbIsNull = false;
			result = HeapTupleGetOid(tuple);
		}
		else /* find oid column */
		{
			bool		isnull;
			Datum		d = caql_getattr_internal(pCtx, tuple, pchn->attnum,
												  &isnull);

			if (!isnull)
			{
				switch (pchn->atttype)
				{
					case OIDOID:
					case REGPROCOID:
						result = DatumGetObjectId(d);
						break;

					default:
						elog(ERROR, "column not an oid: %s\nfile: %s, line %d", 
							 caql_str, filenam, lineno);
				}
			}
			if (pbIsNull)
				*pbIsNull = isnull;
		}
	} /* end HeapTupleIsValid */

	if (pCtx->cq_usesyscache)
	{  
		if (HeapTupleIsValid(tuple))
			ReleaseSysCache(tuple);
	}
	else
	{	
		if (pFetchcount && HeapTupleIsValid(tuple))
		{				
			if (HeapTupleIsValid(systable_getnext(pCtx->cq_sysScan)))
			{
				*pFetchcount = 2;	
			}
		}
		systable_endscan(pCtx->cq_sysScan); 
	}		
	caql_heapclose(pCtx);

	return (result);
} /* end caql_getoid_plus */