Ejemplo n.º 1
0
void case_heap_repalce() {
    struct heap *heap = heap(heap_cmp);
    int a = 3, b = 2, c = 5, d = 7, e = 4, f = 6, g = 1, h = 4;
    assert(heap_push(heap, (void *)&a) == HEAP_OK);
    assert(heap_push(heap, (void *)&b) == HEAP_OK);
    assert(heap_push(heap, (void *)&c) == HEAP_OK);
    assert(heap_push(heap, (void *)&d) == HEAP_OK);
    assert(heap_push(heap, (void *)&e) == HEAP_OK);
    assert(heap_push(heap, (void *)&f) == HEAP_OK);
    assert(heap_push(heap, (void *)&g) == HEAP_OK);
    assert(1 == *(int *)heap_replace(heap, (void *)&h));
    assert(2 == *(int *)heap_pop(heap));
    assert(3 == *(int *)heap_pop(heap));
    assert(4 == *(int *)heap_pop(heap));
    heap_free(heap);
}
Ejemplo n.º 2
0
int32
RelationPurge(char *relationName,
	      char *absoluteTimeString,
	      char *relativeTimeString)
{
    register		i;
    AbsoluteTime		absoluteTime = INVALID_ABSTIME;
    RelativeTime		relativeTime = INVALID_RELTIME;
    bits8			dateTag;
    Relation		relation;
    HeapScanDesc		scan;
    static ScanKeyData	key[1] = {
	{ 0, Anum_pg_class_relname, F_NAMEEQ }
    };
    Buffer			buffer;
    HeapTuple		newTuple, oldTuple;
    AbsoluteTime		currentTime;
    char			*values[Natts_pg_class];
    char			nulls[Natts_pg_class];
    char			replace[Natts_pg_class];
    Relation		idescs[Num_pg_class_indices];
    
    /*
     * XXX for some reason getmyrelids (in inval.c) barfs when
     * you heap_replace tuples from these classes.  i thought
     * setheapoverride would fix it but it didn't.  for now,
     * just disallow purge on these classes.
     */
    if (strcmp(RelationRelationName, relationName) == 0 ||
	strcmp(AttributeRelationName, relationName)  == 0 ||
	strcmp(AccessMethodRelationName, relationName) == 0 ||
	strcmp(AccessMethodOperatorRelationName, relationName) == 0) {
	elog(WARN, "%s: cannot purge catalog \"%s\"",
	     cmdname, relationName);
    }
    
    if (PointerIsValid(absoluteTimeString)) {
	absoluteTime = (int32) nabstimein(absoluteTimeString);
	absoluteTimeString[0] = '\0';
	if (absoluteTime == INVALID_ABSTIME) {
	    elog(NOTICE, "%s: bad absolute time string \"%s\"",
		 cmdname, absoluteTimeString);
	    elog(WARN, "purge not executed");
	}
    }
    
#ifdef	PURGEDEBUG
    elog(DEBUG, "%s: absolute time `%s' is %d.",
	 cmdname, absoluteTimeString, absoluteTime);
#endif	/* defined(PURGEDEBUG) */
    
    if (PointerIsValid(relativeTimeString)) {
	if (isreltime(relativeTimeString, NULL, NULL, NULL) != 1) {
	    elog(WARN, "%s: bad relative time string \"%s\"",
		 cmdname, relativeTimeString);
	}
	relativeTime = reltimein(relativeTimeString);
	
#ifdef	PURGEDEBUG
	elog(DEBUG, "%s: relative time `%s' is %d.",
	     cmdname, relativeTimeString, relativeTime);
#endif	/* defined(PURGEDEBUG) */
    }
    
    /*
     * Find the RELATION relation tuple for the given relation.
     */
    relation = heap_openr(RelationRelationName);
    key[0].sk_argument = PointerGetDatum(relationName);
    fmgr_info(key[0].sk_procedure, &key[0].sk_func, &key[0].sk_nargs);
    
    scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
    oldTuple = heap_getnext(scan, 0, &buffer);
    if (!HeapTupleIsValid(oldTuple)) {
	heap_endscan(scan);
	heap_close(relation);
	elog(WARN, "%s: no such relation: %s", cmdname, relationName);
	return(0);
    }
    
    /*
     * Dig around in the tuple.
     */
    currentTime = GetCurrentTransactionStartTime();
    if (!RelativeTimeIsValid(relativeTime)) {
	dateTag = ABSOLUTE;
	if (!AbsoluteTimeIsValid(absoluteTime))
	    absoluteTime = currentTime;
    } else if (!AbsoluteTimeIsValid(absoluteTime))
	dateTag = RELATIVE;
    else
	dateTag = ABSOLUTE | RELATIVE;
    
    for (i = 0; i < Natts_pg_class; ++i) {
	nulls[i] = heap_attisnull(oldTuple, i+1) ? 'n' : ' ';
	values[i] = NULL;
	replace[i] = ' ';
    }
    if (dateTag & ABSOLUTE) {
	values[Anum_pg_class_relexpires-1] =
	    (char *) UInt32GetDatum(absoluteTime);
	replace[Anum_pg_class_relexpires-1] = 'r';
    }
    if (dateTag & RELATIVE) {
	values[Anum_pg_class_relpreserved-1] =
	    (char *) UInt32GetDatum(relativeTime);
	replace[Anum_pg_class_relpreserved-1] = 'r';
    }
    
    /*
     * Change the RELATION relation tuple for the given relation.
     */
    newTuple = heap_modifytuple(oldTuple, buffer, relation, (Datum*)values,
				nulls, replace);
    
    /* XXX How do you detect an insertion error?? */
    (void) heap_replace(relation, &newTuple->t_ctid, newTuple);
    
    /* keep the system catalog indices current */
    CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
    CatalogIndexInsert(idescs, Num_pg_class_indices, relation, newTuple);
    CatalogCloseIndices(Num_pg_class_indices, idescs);
    
    pfree(newTuple);
    
    heap_endscan(scan);
    heap_close(relation);
    return(1);
}