head	1.10;
access;
symbols
	Version_2_1:1.9
	C_Demo_1:1.3;
locks; strict;
comment	@ * @;


1.10
date	91.11.09.01.47.55;	author mer;	state Exp;
branches;
next	1.9;

1.9
date	91.02.24.00.47.58;	author cimarron;	state Exp;
branches;
next	1.8;

1.8
date	91.01.17.19.13.32;	author sp;	state Exp;
branches;
next	1.7;

1.7
date	91.01.09.19.18.38;	author sp;	state Exp;
branches;
next	1.6;

1.6
date	90.11.10.18.08.07;	author sp;	state Exp;
branches;
next	1.5;

1.5
date	90.10.16.17.23.18;	author sp;	state Exp;
branches;
next	1.4;

1.4
date	89.09.21.19.00.20;	author hirohama;	state Exp;
branches;
next	1.3;

1.3
date	89.09.05.17.26.01;	author mao;	state C_Demo_1;
branches;
next	1.2;

1.2
date	89.03.22.17.36.30;	author muir;	state Stab;
branches;
next	1.1;

1.1
date	89.01.17.05.58.31;	author cimarron;	state Exp;
branches;
next	;


desc
@@


1.10
log
@function prototype additions
@
text
@/*===================================================================
 *
 * FILE:
 * datum.c
 *
 * HEADER:
 * $Header: /users/mer/postgres/src/utils/adt/RCS/datum.c,v 1.9 1991/02/24 00:47:58 cimarron Exp mer $
 *
 * DESCRIPTION:
 *
 * In the implementation of the next routines we assume the following:
 *
 * A) if a type is "byVal" then all the information is stored in the
 * Datum itself (i.e. no pointers involved!). In this case the
 * length of the type is always greater than zero and less than
 * "sizeof(Datum)"
 * B) if a type is not "byVal" and it has a fixed length, then
 * the "Datum" always contain a pointer to a stream of bytes.
 * The number of significant bytes are always equal to the length of the
 * type.
 * C) if a type is not "byVal" and is of variable length (i.e. it has
 * length == -1) then "Datum" always points to a "struct varlena".
 * This varlena structure has information about the actual length of this
 * particular instance of the type and about its value.
 *
 */

#include "tmp/c.h"
#include "tmp/postgres.h"
#include "tmp/datum.h"
#include "catalog/pg_type.h"
#include "utils/log.h"

/* datum.c */
Size datumGetSize ARGS((Datum value , ObjectId type , bool byVal , Size len ));
Datum datumCopy ARGS((Datum value , ObjectId type , bool byVal , Size len ));
void datumFree ARGS((Datum value , ObjectId type , bool byVal , Size len ));
bool datumIsEqual ARGS((Datum value1 , Datum value2 , ObjectId type , bool byVal , Size len ));

/*-------------------------------------------------------------------------
 * datumGetSize
 *
 * Find the "real" size of a datum, given the datum value,
 * its type, whether it is a "by value", and its length.
 *
 * To cut a long story short, usually the real size is equal to the
 * type length, with the exception of variable length types which have
 * a length equal to -1. In this case, we have to look at the value of
 * the datum itself (which is a pointer to a 'varlena' struct) to find
 * its size.
 *-------------------------------------------------------------------------
 */
Size
datumGetSize(value, type, byVal, len)
Datum value;
ObjectId type;
bool byVal;
Size len;
{

    struct varlena *s;
    Size size;

    if (byVal) {
	if (len >= 0 && len <= sizeof(Datum)) {
	    size = len;
	} else {
	    elog(WARN,
		"datumGetSize: Error: type=%ld, byVaL with len=%d",
		(long) type, len);
	}
    } else { /*  not byValue */
	if (len == -1) {
	    /*
	     * variable length type
	     * Look at the varlena struct for its real length...
	     */
	    s = (struct varlena *) DatumGetPointer(value);
	    if (!PointerIsValid(s)) {
		elog(WARN,
		    "datumGetSize: Invalid Datum Pointer");
	    }
	    size = (Size) VARSIZE(s);
	} else {
	    /*
	     * fixed length type
	     */
	    size = len;
	}
    }

    return(size);
}

/*-------------------------------------------------------------------------
 * datumCopy
 *
 * make a copy of a datum
 *
 * If the type of the datum is not passed by value (i.e. "byVal=false")
 * then we assume that the datum contains a pointer and we copy all the
 * bytes pointed by this pointer
 *-------------------------------------------------------------------------
 */
Datum
datumCopy(value, type, byVal, len)
Datum value;
ObjectId type;
bool byVal;
Size len;
{

    Size realSize;
    Datum res;
    Pointer s;

    realSize = datumGetSize(value, type, byVal, len);

    if (byVal) {
	res = value;
    } else {
	/*
	 * the value is a pointer. Allocate enough space
	 * and copy the pointed data.
	 */
	s = (Pointer) palloc(realSize);
	if (s == NULL) {
	    elog(WARN,"datumCopy: out of memory\n");
	}
	bcopy(DatumGetPointer(value), s, realSize);
	res = PointerGetDatum(s);
    }
    return(res);
}

/*-------------------------------------------------------------------------
 * datumFree
 *
 * Free the space occupied by a datum CREATED BY "datumCopy"
 *
 * NOTE: DO NOT USE THIS ROUTINE with datums returned by amgetattr() etc.
 * ONLY datums created by "datumCopy" can be freed!
 *-------------------------------------------------------------------------
 */
void
datumFree(value, type, byVal, len)
Datum value;
ObjectId type;
bool byVal;
Size len;
{

    Size realSize;
    Pointer s;

    realSize = datumGetSize(value, type, byVal, len);

    if (!byVal) {
	/*
	 * free the space palloced by "datumCopy()"
	 */
	s = DatumGetPointer(value);
	pfree(s);
    }
}

/*-------------------------------------------------------------------------
 * datumIsEqual
 *
 * Return true if two datums are equal, false otherwise
 *
 * NOTE: XXX!
 * We just compare the bytes of the two values, one by one.
 * This routine will return false if there are 2 different
 * representations of the same value (something along the lines
 * of say the representation of zero in one's complement arithmetic).
 *
 *-------------------------------------------------------------------------
 */
bool
datumIsEqual(value1, value2, type, byVal, len)
Datum value1;
Datum value2;
ObjectId type;
bool byVal;
Size len;
{
    Size size1, size2;
    char *s1, *s2;

    if (byVal) {
	/*
	 * just compare the two datums.
	 * NOTE: just comparing "len" bytes will not do the
	 * work, because we do not know how these bytes
	 * are aligned inside the "Datum".
	 */
	if (value1 == value2)
	    return(true);
	else
	    return(false);
    } else {
	/*
	 * byVal = false
	 * Compare the bytes pointed by the pointers stored in the
	 * datums.
	 */
	size1 = datumGetSize(value1, type, byVal, len);
	size2 = datumGetSize(value2, type, byVal, len);
	if (size1 != size2)
	    return(false);
	s1 = (char *) DatumGetPointer(value1);
	s2 = (char *) DatumGetPointer(value2);
	if (!bcmp(s1, s2, size1))
	    return(true);
	else
	    return(false);
    }
}
	
@


1.9
log
@added palloc_debug tracing facility
@
text
@d7 1
a7 1
 * $Header: RCS/datum.c,v 1.8 91/01/17 19:13:32 sp Exp Locker: cimarron $
d33 6
@


1.8
log
@When comparing a variable of type "Size" (i.e. unsigned int) with
-1 always use `==' and not `<=' because the later is ALWAYS true !
@
text
@d7 1
a7 1
 * $Header: RCS/datum.c,v 1.7 91/01/09 19:18:38 sp Exp Locker: sp $
a109 1
    char *palloc();
@


1.7
log
@Almost all of the datum routines have been renamed and take different
arguments.
@
text
@d7 1
a7 1
 * $Header: RCS/datum.c,v 1.6 90/11/10 18:08:07 sp Exp $
d67 1
a67 1
	if (len <= -1) {
@


1.6
log
@bug fix: the length of a type must be an int and not an unsigned one,
otherwise when we comapre it with -1 (variable length type) then
anything can happen... (usually the worst possible...)
@
text
@d7 1
a7 1
 * $Header: RCS/datum.c,v 1.5 90/10/16 17:23:18 sp Exp $
d19 1
a19 1
 * The number of significant bytes are always equal to the length of thr
a30 1
#include "catalog/syscache.h"
d35 1
a35 1
 * datumGetRealLengthAndByVal
d37 9
a45 6
 * Given a datum and its type, find the "real" length of the datum's value
 * and if the type is passed "by value" or not.
 * If the type's length is positive (i.e. fixed) then the "real" length is
 * just the type's length.
 * But if it is -1 (i.e. we are dealing with a variable length type)
 * then we have to look at the struct varlena pointed by the datum.
d47 2
a48 2
void
datumGetRealLengthAndByVal(value, type, sizeP, byValP)
d51 2
a52 2
Size *sizeP;
bool *byValP;
a54 3
    long int typeLength;
    HeapTuple typeTuple;
    int i;
d56 1
d58 3
a60 28
    /*---
     * NOTE: XXX!
     * 'typeLength' must be an 'int' and NOT 'Size' which is an unsigned
     * quantity! Otherwise if we compare it with -1 (for variable length
     * types) then .... you guess what happens.....
     */

    /*
     * find the type's "length" and "byVal"
     */
    typeTuple = SearchSysCacheTuple(TYPOID,
				    (char *) type,
				    (char *) NULL,
				    (char *) NULL,
				    (char *) NULL);
    if (!HeapTupleIsValid(typeTuple)) {
	elog(WARN,
	    "datumGetRealLengthAndByVal: Cache lookup of type %ld failed",
	    (long) type);
    }
    typeLength	= ((ObjectId) ((TypeTupleForm)
			GETSTRUCT(typeTuple))->typlen);
    *byValP	= ((bool) ((TypeTupleForm)
			GETSTRUCT(typeTuple))->typbyval);

    if (*byValP) {
	if (typeLength >= 0) {
	    *sizeP = typeLength;
d63 2
a64 2
		"datumGetRealLengthAndByVal: type %ld: (len<0 and byVal)",
		(long) type);
d67 1
a67 1
	if (typeLength <= -1) {
d75 1
a75 1
		    "datumGetRealLengthAndByVal: Invalid Datum Pointer");
d77 1
a77 1
	    *sizeP = (Size) PSIZE(s);
d82 1
a82 1
	    *sizeP = typeLength;
d85 2
d90 1
a90 1
 * copyDatum
d94 1
a94 1
 * If the type of the datum is not passed by value (i.e. "byVal=flase")
d97 1
d100 1
a100 1
copyDatum(value, type)
d103 2
d107 1
a107 2
    Size length;
    bool byVal;
d112 1
a112 1
    datumGetRealLengthAndByVal(value, type, &length, &byVal);
d117 5
a121 1
	s = (Pointer) palloc(length);
d123 1
a123 1
	    elog(WARN,"copyDatum: out of memory\n");
d125 1
a125 1
	bcopy(DatumGetPointer(value), s, length);
d132 1
a132 1
 * freeDatum
d134 1
a134 1
 * Free the space occupied by a datum CREATED BY "copyDatum"
d137 2
a138 1
 * ONLY datums created by "copyDatum" can be freed!
d141 1
a141 1
freeDatum(value, type)
d144 2
d148 1
a148 2
    Size length;
    bool byVal;
d151 1
a151 1
    datumGetRealLengthAndByVal(value, type, &length, &byVal);
d155 1
a155 1
	 * free the space palloced by "copyDatum()"
d161 55
@


1.5
log
@This is actually a completely new file now
It contains Datum related utility routines...
@
text
@d7 1
a7 1
 * $Header: $
d53 1
a53 1
    Size typeLength;
d57 7
@


1.4
log
@tructure -> truct
@
text
@d1 25
a25 3
/*
 * datum.c --
 *	POSTGRES abstract data type datum representation code.
d28 6
a33 1
#include "c.h"
d35 9
a43 8
RcsId("$Header: RCS/datum.c,v 1.3 89/09/05 17:26:01 mao C_Demo_1 Locker: hirohama $");

#include "datum.h"


/*
 * DatumGet --
 *	Datum accessor macro.
d45 7
a51 1
#define DatumGet(datum, field)	(datum.field.value)
d53 4
a56 5
/*
 * DatumSet --
 *	Datum assignment macro.
 */
#define DatumSet(datum, field, newValue)	(datum.field.value) = newValue
d58 17
a74 12
char
DatumGetChar(datum)
	Datum	datum;
{
	return (DatumGet(datum, character));
}

Datum
CharGetDatum(character)
	char	character;
{
	Datum	datum;
d76 27
a102 3
	bzero(&datum, sizeof(Datum));
	DatumSet(datum, character, character);
	return (datum);
d105 9
a113 7
int8
DatumGetInt8(datum)
	Datum	datum;
{
	return (DatumGet(datum, integer8));
}

d115 3
a117 2
Int8GetDatum(integer8)
	int8	integer8;
a118 1
	Datum	datum;
d120 5
a124 4
	bzero(&datum, sizeof(Datum));
	DatumSet(datum, integer8, AsInt8(integer8));
	return (datum);
}
d126 1
a126 6
uint8
DatumGetUInt8(datum)
	Datum	datum;
{
	return (DatumGet(datum, unsignedInteger8));
}
d128 11
a138 9
Datum
UInt8GetDatum(unsignedInteger8)
	uint8	unsignedInteger8;
{
	Datum	datum;

	bzero(&datum, sizeof(Datum));
	DatumSet(datum, unsignedInteger8, AsUint8(unsignedInteger8));
	return (datum);
d141 12
a152 3
int16
DatumGetInt16(datum)
	Datum	datum;
a153 2
	return (DatumGet(datum, integer16));
}
d155 3
a157 5
Datum
Int16GetDatum(integer16)
	int16	integer16;
{
	Datum	datum;
d159 1
a159 4
	bzero(&datum, sizeof(Datum));
	DatumSet(datum, integer16, integer16);
	return (datum);
}
d161 7
a167 178
uint16
DatumGetUInt16(datum)
	Datum	datum;
{
	return (DatumGet(datum, unsignedInteger16));
}

Datum
UInt16GetDatum(unsignedInteger16)
	uint16	unsignedInteger16;
{
	Datum	datum;

	bzero(&datum, sizeof(Datum));
	DatumSet(datum, unsignedInteger16, unsignedInteger16);
	return (datum);
}

int32
DatumGetInt32(datum)
	Datum	datum;
{
	return (DatumGet(datum, integer32));
}

Datum
Int32GetDatum(integer32)
	int32	integer32;
{
	Datum	datum;

	bzero(&datum, sizeof(Datum));
	DatumSet(datum, integer32, integer32);
	return (datum);
}

uint32
DatumGetUInt32(datum)
	Datum	datum;
{
	return (DatumGet(datum, unsignedInteger32));
}

Datum
UInt32GetDatum(unsignedInteger32)
	uint32	unsignedInteger32;
{
	Datum	datum;

	bzero(&datum, sizeof(Datum));
	DatumSet(datum, unsignedInteger32, unsignedInteger32);
	return (datum);
}

float32
DatumGetFloat32(datum)
	Datum	datum;
{
	return (DatumGet(datum, smallFloat));
}

Datum
Float32GetDatum(smallFloat)
	float32	smallFloat;
{
	Datum	datum;

	bzero(&datum, sizeof(Datum));
	DatumSet(datum, smallFloat, smallFloat);
	return (datum);
}

float64
DatumGetFloat64(datum)
	Datum	datum;
{
	return (DatumGet(datum, largeFloat));
}

Datum
Float64GetDatum(largeFloat)
	float64	largeFloat;
{
	Datum	datum;

	bzero(&datum, sizeof(Datum));
	DatumSet(datum, largeFloat, largeFloat);
	return (datum);
}

Pointer
DatumGetPointer(datum)
	Datum	datum;
{
	return (DatumGet(datum, pointer));
}

Datum
PointerGetDatum(pointer)
	Pointer	pointer;
{
	Datum	datum;

	bzero(&datum, sizeof(Datum));
	DatumSet(datum, pointer, pointer);
	return (datum);
}

Pointer *
DatumGetPointerPointer(datum)
	Datum	datum;
{
	return (DatumGet(datum, pointerPointer));
}

Datum
PointerPointerGetDatum(pointerPointerInP)
	Pointer	*pointerPointerInP;
{
	Datum	datum;

	bzero(&datum, sizeof(Datum));
	DatumSet(datum, pointerPointer, pointerPointerInP);
	return (datum);
}

AnyStruct *
DatumGetStructPointer(datum)
	Datum	datum;
{
	return (DatumGet(datum, structPointer));
}

Datum
StructPointerGetDatum(structPointerInP)
	AnyStruct	*structPointerInP;
{
	Datum	datum;

	bzero(&datum, sizeof(Datum));
	DatumSet(datum, structPointer, structPointerInP);
	return (datum);
}

Name
DatumGetName(datum)
	Datum	datum;
{
	return (DatumGet(datum, name));
}

Datum
NameGetDatum(name)
	Name	name;
{
	Datum	datum;

	bzero(&datum, sizeof(Datum));
	DatumSet(datum, name, name);
	return (datum);
}

ObjectId
DatumGetObjectId(datum)
	Datum	datum;
{
	return (DatumGet(datum, objectId));
}

Datum
ObjectIdGetDatum(objectId)
	ObjectId	objectId;
{
	Datum	datum;

	bzero(&datum, sizeof(Datum));
	DatumSet(datum, objectId, objectId);
	return (datum);
@


1.3
log
@Working version of C-only demo
@
text
@d8 2
a11 1
RcsId("$Header: /usr6/postgres/mao/postgres/src/utils/adt/RCS/datum.c,v 1.2 89/03/22 17:36:30 muir Stab $");
d223 2
a224 2
AnyStructure *
DatumGetStructurePointer(datum)
d227 1
a227 1
	return (DatumGet(datum, structurePointer));
d231 2
a232 2
StructurePointerGetDatum(structurePointerInP)
	AnyStructure	*structurePointerInP;
d237 1
a237 1
	DatumSet(datum, structurePointer, structurePointerInP);
@


1.2
log
@copyright removal
@
text
@d10 1
a10 1
RcsId("$Header: /usr6/postgres/muir/postgres/src/utils/adt/RCS/datum.c,v 1.1 89/01/17 05:58:31 cimarron Exp $");
@


1.1
log
@Initial revision
@
text
@a0 1

a1 26
 * 
 * POSTGRES Data Base Management System
 * 
 * Copyright (c) 1988 Regents of the University of California
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for educational, research, and non-profit purposes and
 * without fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation, and that
 * the name of the University of California not be used in advertising
 * or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Permission to incorporate this
 * software into commercial products can be obtained from the Campus
 * Software Office, 295 Evans Hall, University of California, Berkeley,
 * Ca., 94720 provided only that the the requestor give the University
 * of California a free licence to any derived software for educational
 * and research purposes.  The University of California makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 * 
 */



/*
d10 1
a10 1
RcsId("$Header: datum.c,v 1.1 88/11/11 16:35:42 postgres Exp $");
@
