/*
 * This tests if non-equal predicates also use index scan.
 */
void
test__caql_switch5(void **state)
{
	const char		   *query = "SELECT * FROM pg_attribute "
								"WHERE attrelid = :1 and attnum > :2";
	struct caql_hash_cookie *hash_cookie;
	cqContext			context = {0}, *pCtx;
	Datum				keys[] = {ObjectIdGetDatum(ProcedureRelationId),
								  Int16GetDatum(0)};
	cq_list			   *pcql = CaQL(query, 2, keys);
	RelationData		dummyrel;
	SysScanDescData		dummydesc;

	dummyrel.rd_id = AttributeRelationId;

	hash_cookie = cq_lookup(query, strlen(query), pcql);

	/*
	 * Add explicit relation, and set indexOK = true and syscache = false.
	 */
	pCtx = caql_addrel(cqclr(&context), &dummyrel);
	pCtx = caql_indexOK(pCtx, true);
	pCtx = caql_syscache(pCtx, false);

	/* setup ScanKeyInit */
	expect__ScanKeyInit(NULL, false,
						Anum_pg_attribute_attrelid, true,
						BTEqualStrategyNumber, true,
						F_OIDEQ, true,
						NULL, false);

	/* setup ScanKeyInit */
	expect__ScanKeyInit(NULL, false,
						Anum_pg_attribute_attnum, true,
						BTGreaterStrategyNumber, true,
						F_INT2GT, true,
						NULL, false);

	/* setup systable_beginscan */
	expect__systable_beginscan(&dummyrel, true,
							   AttributeRelidNumIndexId, true,
							   true, true,
							   SnapshotNow, true,
							   2, true,
							   NULL, false,
							   &dummydesc);

	pCtx = caql_switch(hash_cookie, pCtx, pcql);

	assert_true(pCtx != NULL);
	assert_true(pCtx->cq_sysScan == &dummydesc);
	assert_true(pCtx->cq_heap_rel == &dummyrel);
	assert_false(pCtx->cq_usesyscache);
	assert_true(pCtx->cq_useidxOK);
}
Example #2
0
void 
InitResQueues(void)
{

	HeapTuple			tuple;
	int					numQueues = 0;
	bool				queuesok = true;
	cqContext		   *pcqCtx;
	cqContext			cqc;
	
	Assert(ResScheduler);

	/*
	 * Need a resource owner to keep the heapam code happy.
	 */
	Assert(CurrentResourceOwner == NULL);

	ResourceOwner owner = ResourceOwnerCreate(NULL, "InitQueues");
	CurrentResourceOwner = owner;
	
	/**
	 * The resqueue shared mem initialization must be serialized. Only the first session
	 * should do the init.
	 * Serialization is done the ResQueueLock LW_EXCLUSIVE. However, we must obtain all DB
	 * lock before obtaining LWlock.
	 * So, we must have obtained ResQueueRelationId and ResQueueCapabilityRelationId lock
	 * first.
	 */
	Relation relResqueue = heap_open(ResQueueRelationId, AccessShareLock);
	LockRelationOid(ResQueueCapabilityRelationId, RowExclusiveLock);
	LWLockAcquire(ResQueueLock, LW_EXCLUSIVE);

	if (ResScheduler->num_queues > 0)
	{
		/* Hash table has already been loaded */
		LWLockRelease(ResQueueLock);
		UnlockRelationOid(ResQueueCapabilityRelationId, RowExclusiveLock);
		heap_close(relResqueue, AccessShareLock);
		CurrentResourceOwner = NULL;
		ResourceOwnerDelete(owner);
		return;
	}

	/* XXX XXX: should this be rowexclusive ? */
	pcqCtx = caql_beginscan(
			caql_indexOK(
					caql_addrel(cqclr(&cqc), relResqueue),
					false),
			cql("SELECT * FROM pg_resqueue ", NULL));

	while (HeapTupleIsValid(tuple = caql_getnext(pcqCtx)))
	{
		Form_pg_resqueue	queueform;
		Oid					queueid;
		bool				overcommit;
		float4				ignorelimit;
		Cost				thresholds[NUM_RES_LIMIT_TYPES];
		char				*queuename;

		numQueues++;

		queueform = (Form_pg_resqueue) GETSTRUCT(tuple);

		queueid = HeapTupleGetOid(tuple);
		queuename = NameStr(queueform->rsqname);
		thresholds[RES_COUNT_LIMIT] = queueform->rsqcountlimit;
		thresholds[RES_COST_LIMIT] = queueform->rsqcostlimit;

		thresholds[RES_MEMORY_LIMIT] = ResourceQueueGetMemoryLimit(queueid);
		overcommit = queueform->rsqovercommit;
		ignorelimit = queueform->rsqignorecostlimit;
		queuesok = ResCreateQueue(queueid, thresholds, overcommit, ignorelimit);

		if (!queuesok)
		{
			/** Break out of loop. Close relations, relinquish LWLock and then error out */ 
			break;
		}
	}

	caql_endscan(pcqCtx);
	LWLockRelease(ResQueueLock);
	UnlockRelationOid(ResQueueCapabilityRelationId, RowExclusiveLock);
	heap_close(relResqueue, AccessShareLock);

	if (!queuesok)
		ereport(PANIC,
			(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
			 errmsg("insufficient resource queues available"),
		errhint("Increase max_resource_queues to %d.", numQueues)));


	elog(LOG,"initialized %d resource queues", numQueues);

	CurrentResourceOwner = NULL;
	ResourceOwnerDelete(owner);

	return;
}