datum.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:5k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * datum.c
  4.  *
  5.  * Copyright (c) 1994, Regents of the University of California
  6.  *
  7.  *
  8.  * IDENTIFICATION
  9.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/utils/adt/datum.c,v 1.12.2.1 1999/08/02 05:24:51 scrappy Exp $
  10.  *
  11.  *-------------------------------------------------------------------------
  12.  */
  13. /*
  14.  * In the implementation of the next routines we assume the following:
  15.  *
  16.  * A) if a type is "byVal" then all the information is stored in the
  17.  * Datum itself (i.e. no pointers involved!). In this case the
  18.  * length of the type is always greater than zero and less than
  19.  * "sizeof(Datum)"
  20.  * B) if a type is not "byVal" and it has a fixed length, then
  21.  * the "Datum" always contain a pointer to a stream of bytes.
  22.  * The number of significant bytes are always equal to the length of the
  23.  * type.
  24.  * C) if a type is not "byVal" and is of variable length (i.e. it has
  25.  * length == -1) then "Datum" always points to a "struct varlena".
  26.  * This varlena structure has information about the actual length of this
  27.  * particular instance of the type and about its value.
  28.  *
  29.  */
  30. #include "postgres.h"
  31. #include "utils/datum.h"
  32. /*-------------------------------------------------------------------------
  33.  * datumGetSize
  34.  *
  35.  * Find the "real" size of a datum, given the datum value,
  36.  * its type, whether it is a "by value", and its length.
  37.  *
  38.  * To cut a long story short, usually the real size is equal to the
  39.  * type length, with the exception of variable length types which have
  40.  * a length equal to -1. In this case, we have to look at the value of
  41.  * the datum itself (which is a pointer to a 'varlena' struct) to find
  42.  * its size.
  43.  *-------------------------------------------------------------------------
  44.  */
  45. Size
  46. datumGetSize(Datum value, Oid type, bool byVal, Size len)
  47. {
  48. struct varlena *s;
  49. Size size = 0;
  50. if (byVal)
  51. {
  52. if (len <= sizeof(Datum))
  53. size = len;
  54. else
  55. {
  56. elog(ERROR,
  57.  "datumGetSize: Error: type=%ld, byVaL with len=%d",
  58.  (long) type, len);
  59. }
  60. }
  61. else
  62. { /* not byValue */
  63. if (len == -1)
  64. {
  65. /*
  66.  * variable length type Look at the varlena struct for its
  67.  * real length...
  68.  */
  69. s = (struct varlena *) DatumGetPointer(value);
  70. if (!PointerIsValid(s))
  71. {
  72. elog(ERROR,
  73.  "datumGetSize: Invalid Datum Pointer");
  74. }
  75. size = (Size) VARSIZE(s);
  76. }
  77. else
  78. {
  79. /*
  80.  * fixed length type
  81.  */
  82. size = len;
  83. }
  84. }
  85. return size;
  86. }
  87. /*-------------------------------------------------------------------------
  88.  * datumCopy
  89.  *
  90.  * make a copy of a datum
  91.  *
  92.  * If the type of the datum is not passed by value (i.e. "byVal=false")
  93.  * then we assume that the datum contains a pointer and we copy all the
  94.  * bytes pointed by this pointer
  95.  *-------------------------------------------------------------------------
  96.  */
  97. Datum
  98. datumCopy(Datum value, Oid type, bool byVal, Size len)
  99. {
  100. Size realSize;
  101. Datum res;
  102. char    *s;
  103. if (byVal)
  104. res = value;
  105. else
  106. {
  107. if (value == 0)
  108. return (Datum) NULL;
  109. realSize = datumGetSize(value, type, byVal, len);
  110. /*
  111.  * the value is a pointer. Allocate enough space and copy the
  112.  * pointed data.
  113.  */
  114. s = (char *) palloc(realSize);
  115. if (s == NULL)
  116. elog(ERROR, "datumCopy: out of memoryn");
  117. memmove(s, DatumGetPointer(value), realSize);
  118. res = (Datum) s;
  119. }
  120. return res;
  121. }
  122. /*-------------------------------------------------------------------------
  123.  * datumFree
  124.  *
  125.  * Free the space occupied by a datum CREATED BY "datumCopy"
  126.  *
  127.  * NOTE: DO NOT USE THIS ROUTINE with datums returned by amgetattr() etc.
  128.  * ONLY datums created by "datumCopy" can be freed!
  129.  *-------------------------------------------------------------------------
  130.  */
  131. #ifdef NOT_USED
  132. void
  133. datumFree(Datum value, Oid type, bool byVal, Size len)
  134. {
  135. Size realSize;
  136. Pointer s;
  137. realSize = datumGetSize(value, type, byVal, len);
  138. if (!byVal)
  139. {
  140. /*
  141.  * free the space palloced by "datumCopy()"
  142.  */
  143. s = DatumGetPointer(value);
  144. pfree(s);
  145. }
  146. }
  147. #endif
  148. /*-------------------------------------------------------------------------
  149.  * datumIsEqual
  150.  *
  151.  * Return true if two datums are equal, false otherwise
  152.  *
  153.  * NOTE: XXX!
  154.  * We just compare the bytes of the two values, one by one.
  155.  * This routine will return false if there are 2 different
  156.  * representations of the same value (something along the lines
  157.  * of say the representation of zero in one's complement arithmetic).
  158.  *
  159.  *-------------------------------------------------------------------------
  160.  */
  161. bool
  162. datumIsEqual(Datum value1, Datum value2, Oid type, bool byVal, Size len)
  163. {
  164. Size size1,
  165. size2;
  166. char    *s1,
  167.    *s2;
  168. if (byVal)
  169. {
  170. /*
  171.  * just compare the two datums. NOTE: just comparing "len" bytes
  172.  * will not do the work, because we do not know how these bytes
  173.  * are aligned inside the "Datum".
  174.  */
  175. if (value1 == value2)
  176. return true;
  177. else
  178. return false;
  179. }
  180. else
  181. {
  182. /*
  183.  * byVal = false Compare the bytes pointed by the pointers stored
  184.  * in the datums.
  185.  */
  186. size1 = datumGetSize(value1, type, byVal, len);
  187. size2 = datumGetSize(value2, type, byVal, len);
  188. if (size1 != size2)
  189. return false;
  190. s1 = (char *) DatumGetPointer(value1);
  191. s2 = (char *) DatumGetPointer(value2);
  192. if (!memcmp(s1, s2, size1))
  193. return true;
  194. else
  195. return false;
  196. }
  197. }