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

数据库系统

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.   This file contains routines that can be bound to a Postgres backend and
  3.   called by the backend in the process of processing queries.  The calling
  4.   format for these routines is dictated by Postgres architecture.
  5. ******************************************************************************/
  6. #include <stdio.h>
  7. /* do not include libpq-fe.h for backend-loaded functions*/
  8. /* #include "libpq-fe.h"  */
  9. #include "postgres.h"
  10. #include "utils/mcxt.h"
  11. typedef struct Complex
  12. {
  13. double x;
  14. double y;
  15. } Complex;
  16. /* These prototypes declare the requirements that Postgres places on these
  17.    user written functions.
  18. */
  19. Complex    *complex_in(char *str);
  20. char    *complex_out(Complex * complex);
  21. Complex    *complex_add(Complex * a, Complex * b);
  22. bool complex_abs_lt(Complex * a, Complex * b);
  23. bool complex_abs_le(Complex * a, Complex * b);
  24. bool complex_abs_eq(Complex * a, Complex * b);
  25. bool complex_abs_ge(Complex * a, Complex * b);
  26. bool complex_abs_gt(Complex * a, Complex * b);
  27. int4 complex_abs_cmp(Complex * a, Complex * b);
  28. /*****************************************************************************
  29.  * Input/Output functions
  30.  *****************************************************************************/
  31. Complex    *
  32. complex_in(char *str)
  33. {
  34. double x,
  35. y;
  36. Complex    *result;
  37. if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
  38. {
  39. elog(ERROR, "complex_in: error in parsing "%s"", str);
  40. return NULL;
  41. }
  42. result = (Complex *) palloc(sizeof(Complex));
  43. result->x = x;
  44. result->y = y;
  45. return result;
  46. }
  47. /*
  48.  * You might have noticed a slight inconsistency between the following
  49.  * declaration and the SQL definition:
  50.  *    CREATE FUNCTION complex_out(opaque) RETURNS opaque ...
  51.  * The reason is that the argument pass into complex_out is really just a
  52.  * pointer. POSTGRES thinks all output functions are:
  53.  *    char *out_func(char *);
  54.  */
  55. char *
  56. complex_out(Complex * complex)
  57. {
  58. char    *result;
  59. if (complex == NULL)
  60. return NULL;
  61. result = (char *) palloc(60);
  62. sprintf(result, "(%g,%g)", complex->x, complex->y);
  63. return result;
  64. }
  65. /*****************************************************************************
  66.  * New Operators
  67.  *****************************************************************************/
  68. Complex    *
  69. complex_add(Complex * a, Complex * b)
  70. {
  71. Complex    *result;
  72. result = (Complex *) palloc(sizeof(Complex));
  73. result->x = a->x + b->x;
  74. result->y = a->y + b->y;
  75. return result;
  76. }
  77. /*****************************************************************************
  78.  * Operator class for defining B-tree index
  79.  *****************************************************************************/
  80. #define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
  81. bool
  82. complex_abs_lt(Complex * a, Complex * b)
  83. {
  84. double amag = Mag(a),
  85. bmag = Mag(b);
  86. return amag < bmag;
  87. }
  88. bool
  89. complex_abs_le(Complex * a, Complex * b)
  90. {
  91. double amag = Mag(a),
  92. bmag = Mag(b);
  93. return amag <= bmag;
  94. }
  95. bool
  96. complex_abs_eq(Complex * a, Complex * b)
  97. {
  98. double amag = Mag(a),
  99. bmag = Mag(b);
  100. return amag == bmag;
  101. }
  102. bool
  103. complex_abs_ge(Complex * a, Complex * b)
  104. {
  105. double amag = Mag(a),
  106. bmag = Mag(b);
  107. return amag >= bmag;
  108. }
  109. bool
  110. complex_abs_gt(Complex * a, Complex * b)
  111. {
  112. double amag = Mag(a),
  113. bmag = Mag(b);
  114. return amag > bmag;
  115. }
  116. int4
  117. complex_abs_cmp(Complex * a, Complex * b)
  118. {
  119. double amag = Mag(a),
  120. bmag = Mag(b);
  121. if (amag < bmag)
  122. return -1;
  123. else if (amag > bmag)
  124. return 1;
  125. else
  126. return 0;
  127. }
  128. /*****************************************************************************
  129.  * test code
  130.  *****************************************************************************/
  131. /*
  132.  * You should always test your code separately. Trust me, using POSTGRES to
  133.  * debug your C function will be very painful and unproductive. In case of
  134.  * POSTGRES crashing, it is impossible to tell whether the bug is in your
  135.  * code or POSTGRES's.
  136.  */
  137. void test_main(void);
  138. void
  139. test_main()
  140. {
  141. Complex    *a;
  142. Complex    *b;
  143. a = complex_in("(4.01, 3.77 )");
  144. printf("a = %sn", complex_out(a));
  145. b = complex_in("(1.0,2.0)");
  146. printf("b = %sn", complex_out(b));
  147. printf("a +  b = %sn", complex_out(complex_add(a, b)));
  148. printf("a <  b = %dn", complex_abs_lt(a, b));
  149. printf("a <= b = %dn", complex_abs_le(a, b));
  150. printf("a =  b = %dn", complex_abs_eq(a, b));
  151. printf("a >= b = %dn", complex_abs_ge(a, b));
  152. printf("a >  b = %dn", complex_abs_gt(a, b));
  153. }