Skip to content
Snippets Groups Projects
Select Git revision
  • benchmark-tools
  • postgres-lambda
  • master default
  • REL9_4_25
  • REL9_5_20
  • REL9_6_16
  • REL_10_11
  • REL_11_6
  • REL_12_1
  • REL_12_0
  • REL_12_RC1
  • REL_12_BETA4
  • REL9_4_24
  • REL9_5_19
  • REL9_6_15
  • REL_10_10
  • REL_11_5
  • REL_12_BETA3
  • REL9_4_23
  • REL9_5_18
  • REL9_6_14
  • REL_10_9
  • REL_11_4
23 results

datum.c

Blame
  • datum.c 5.02 KiB
    /*-------------------------------------------------------------------------
     *
     * datum.c
     *	  POSTGRES Datum (abstract data type) manipulation routines.
     *
     * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
     * Portions Copyright (c) 1994, Regents of the University of California
     *
     *
     * IDENTIFICATION
     *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/datum.c,v 1.18 2000/07/12 02:37:19 tgl Exp $
     *
     *-------------------------------------------------------------------------
     */
    /*
     * 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 not more 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.
     *
     * Note that we do not treat "toasted" datums specially; therefore what
     * will be copied or compared is the compressed data or toast reference.
     */
    
    #include "postgres.h"
    
    #include "utils/datum.h"
    
    /*-------------------------------------------------------------------------
     * datumGetSize
     *
     * Find the "real" size of a datum, given the datum value,
     * 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(Datum value, bool typByVal, int typLen)
    {
    	Size		size;
    
    	if (typByVal)
    	{
    		/* Pass-by-value types are always fixed-length */
    		Assert(typLen > 0 && typLen <= sizeof(Datum));
    		size = (Size) typLen;
    	}
    	else
    	{
    		if (typLen == -1)
    		{
    			/* Assume it is a varlena datatype */
    			struct varlena *s = (struct varlena *) DatumGetPointer(value);
    
    			if (!PointerIsValid(s))
    				elog(ERROR, "datumGetSize: Invalid Datum Pointer");
    			size = (Size) VARSIZE(s);
    		}
    		else
    		{
    			/* Fixed-length pass-by-ref type */
    			size = (Size) typLen;
    		}
    	}
    
    	return size;
    }
    
    /*-------------------------------------------------------------------------
     * datumCopy
     *
     * make a copy of a datum
     *
     * If the datatype is pass-by-reference, memory is obtained with palloc().
     *-------------------------------------------------------------------------
     */
    Datum
    datumCopy(Datum value, bool typByVal, int typLen)
    {
    	Datum		res;
    
    	if (typByVal)
    		res = value;
    	else
    	{
    		Size		realSize;
    		char	   *s;
    
    		if (DatumGetPointer(value) == NULL)
    			return PointerGetDatum(NULL);
    
    		realSize = datumGetSize(value, typByVal, typLen);
    
    		s = (char *) palloc(realSize);
    		memcpy(s, DatumGetPointer(value), 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!
     *-------------------------------------------------------------------------
     */
    #ifdef NOT_USED
    void
    datumFree(Datum value, bool typByVal, int typLen)
    {
    	if (!typByVal)
    	{
    		Pointer		s = DatumGetPointer(value);
    
    		pfree(s);
    	}
    }
    
    #endif
    
    /*-------------------------------------------------------------------------
     * 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).
     * Also, it will probably not give the answer you want if either
     * datum has been "toasted".
     *-------------------------------------------------------------------------
     */
    bool
    datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
    {
    	bool	res;
    
    	if (typByVal)
    	{
    		/*
    		 * 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".
    		 */
    		res = (value1 == value2);
    	}
    	else
    	{
    		Size		size1,
    					size2;
    		char	   *s1,
    				   *s2;
    
    		/*
    		 * Compare the bytes pointed by the pointers stored in the datums.
    		 */
    		size1 = datumGetSize(value1, typByVal, typLen);
    		size2 = datumGetSize(value2, typByVal, typLen);
    		if (size1 != size2)
    			return false;
    		s1 = (char *) DatumGetPointer(value1);
    		s2 = (char *) DatumGetPointer(value2);
    		res = (memcmp(s1, s2, size1) == 0);
    	}
    	return res;
    }