aboutsummaryrefslogtreecommitdiff
path: root/src/tutorial/C-code
diff options
context:
space:
mode:
authorMarc G. Fournier <scrappy@hub.org>1996-07-09 06:22:35 +0000
committerMarc G. Fournier <scrappy@hub.org>1996-07-09 06:22:35 +0000
commitd31084e9d1118b25fd16580d9d8c2924b5740dff (patch)
tree3179e66307d54df9c7b966543550e601eb55e668 /src/tutorial/C-code
downloadpostgresql-d31084e9d1118b25fd16580d9d8c2924b5740dff.tar.gz
postgresql-d31084e9d1118b25fd16580d9d8c2924b5740dff.zip
Postgres95 1.01 Distribution - Virgin SourcesPG95-1_01
Diffstat (limited to 'src/tutorial/C-code')
-rw-r--r--src/tutorial/C-code/beard.c64
-rw-r--r--src/tutorial/C-code/complex.c150
-rw-r--r--src/tutorial/C-code/funcs.c56
3 files changed, 270 insertions, 0 deletions
diff --git a/src/tutorial/C-code/beard.c b/src/tutorial/C-code/beard.c
new file mode 100644
index 00000000000..0fe289c8d2b
--- /dev/null
+++ b/src/tutorial/C-code/beard.c
@@ -0,0 +1,64 @@
+/*-------------------------------------------------------------------------
+ *
+ * beard.c--
+ * sample routines to use large objects
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/tutorial/C-code/Attic/beard.c,v 1.1.1.1 1996/07/09 06:22:34 scrappy Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+typedef struct ImageHdr {
+ int size;
+} ImageHdr;
+
+#define BUFSIZE 10
+
+/*
+ * beard -
+ * clips lower 1/3 of picture and return as large object
+ */
+Oid
+beard(Oid picture)
+{
+ Oid beard;
+ int pic_fd, beard_fd;
+ ImageHdr ihdr;
+ char buf[BUFSIZE];
+ int cc;
+
+ if ((pic_fd = lo_open(picture, INV_READ)) == -1)
+ elog(WARN, "Cannot access picture large object");
+
+ if (lo_read(pic_fd, (char*)&ihdr, sizeof(ihdr)) != sizeof(ihdr))
+ elog(WARN, "Picture large object corrupted");
+
+ beardOffset = (ihdr.size / 3) * 2;
+
+ /*
+ * new large object
+ */
+ if ((beard = lo_creat(INV_MD)) == 0) /* ?? is this right? */
+ elog(WARN, "Cannot create new large object");
+
+ if ((beard_fd = lo_open(beard, INV_WRITE)) == -1)
+ elog(WARN, "Cannot access beard large object");
+
+ lo_lseek(pic_fd, beardOffset, SET_CUR);
+ while ((cc = lo_read(pic_fd, buf, BUFSIZE)) > 0) {
+ if (lo_write(beard_fd, buf, cc) != cc)
+ elog(WARN, "error while writing large object");
+ }
+
+ lo_close(pic_fd);
+ lo_close(beard_fd);
+
+ return beard;
+}
+
+
+
diff --git a/src/tutorial/C-code/complex.c b/src/tutorial/C-code/complex.c
new file mode 100644
index 00000000000..bebdd511d4d
--- /dev/null
+++ b/src/tutorial/C-code/complex.c
@@ -0,0 +1,150 @@
+#include <stdio.h>
+/* do not include libpq-fe.h for backend-loaded functions*/
+/* #include "libpq-fe.h" */
+#include "postgres.h"
+#include "utils/elog.h"
+#include "utils/palloc.h"
+#include "utils/mcxt.h"
+
+typedef struct Complex {
+ double x;
+ double y;
+} Complex;
+
+/*****************************************************************************
+ * Input/Output functions
+ *****************************************************************************/
+
+Complex *
+complex_in(char *str)
+{
+ double x, y;
+ Complex *result;
+
+ if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2) {
+ elog(WARN, "complex_in: error in parsing \"%s\"", str);
+ return NULL;
+ }
+ result = (Complex *)palloc(sizeof(Complex));
+ result->x = x;
+ result->y = y;
+ return (result);
+}
+
+/*
+ * You might have noticed a slight inconsistency between the following
+ * declaration and the SQL definition:
+ * CREATE FUNCTION complex_out(opaque) RETURNS opaque ...
+ * The reason is that the argument pass into complex_out is really just a
+ * pointer. POSTGRES thinks all output functions are:
+ * char *out_func(char *);
+ */
+char *
+complex_out(Complex *complex)
+{
+ char *result;
+
+ if (complex == NULL)
+ return(NULL);
+
+ result = (char *) palloc(60);
+ sprintf(result, "(%lg,%lg)", complex->x, complex->y);
+ return(result);
+}
+
+/*****************************************************************************
+ * New Operators
+ *****************************************************************************/
+
+Complex *
+complex_add(Complex *a, Complex *b)
+{
+ Complex *result;
+
+ result = (Complex *)palloc(sizeof(Complex));
+ result->x = a->x + b->x;
+ result->y = a->y + b->y;
+ return (result);
+}
+
+
+/*****************************************************************************
+ * Operator class for defining B-tree index
+ *****************************************************************************/
+
+#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
+
+bool
+complex_abs_lt(Complex *a, Complex *b)
+{
+ double amag = Mag(a), bmag = Mag(b);
+ return (amag<bmag);
+}
+
+bool
+complex_abs_le(Complex *a, Complex *b)
+{
+ double amag = Mag(a), bmag = Mag(b);
+ return (amag<=bmag);
+}
+
+bool
+complex_abs_eq(Complex *a, Complex *b)
+{
+ double amag = Mag(a), bmag = Mag(b);
+ return (amag==bmag);
+}
+
+bool
+complex_abs_ge(Complex *a, Complex *b)
+{
+ double amag = Mag(a), bmag = Mag(b);
+ return (amag>=bmag);
+}
+
+bool
+complex_abs_gt(Complex *a, Complex *b)
+{
+ double amag = Mag(a), bmag = Mag(b);
+ return (amag>bmag);
+}
+
+int4
+complex_abs_cmp(Complex *a, Complex *b)
+{
+ double amag = Mag(a), bmag = Mag(b);
+ if (a < b)
+ return -1;
+ else if (a > b)
+ return 1;
+ else
+ return 0;
+}
+
+/*****************************************************************************
+ * test code
+ *****************************************************************************/
+
+/*
+ * You should always test your code separately. Trust me, using POSTGRES to
+ * debug your C function will be very painful and unproductive. In case of
+ * POSTGRES crashing, it is impossible to tell whether the bug is in your
+ * code or POSTGRES's.
+ */
+void
+test_main()
+{
+ Complex *a;
+ Complex *b;
+
+ a = complex_in("(4.01, 3.77 )");
+ printf("a = %s\n", complex_out(a));
+ b = complex_in("(1.0,2.0)");
+ printf("b = %s\n", complex_out(b));
+ printf("a + b = %s\n", complex_out(complex_add(a,b)));
+ printf("a < b = %d\n", complex_abs_lt(a,b));
+ printf("a <= b = %d\n", complex_abs_le(a,b));
+ printf("a = b = %d\n", complex_abs_eq(a,b));
+ printf("a >= b = %d\n", complex_abs_ge(a,b));
+ printf("a > b = %d\n", complex_abs_gt(a,b));
+}
diff --git a/src/tutorial/C-code/funcs.c b/src/tutorial/C-code/funcs.c
new file mode 100644
index 00000000000..f91b4d62058
--- /dev/null
+++ b/src/tutorial/C-code/funcs.c
@@ -0,0 +1,56 @@
+#include <string.h>
+#include <stdio.h>
+#include "postgres.h" /* for char16, etc. */
+#include "utils/palloc.h" /* for palloc */
+#include "libpq-fe.h" /* for TUPLE */
+
+int
+add_one(int arg)
+{
+ return(arg + 1);
+}
+
+char16 *
+concat16(char16 *arg1, char16 *arg2)
+{
+ char16 *new_c16 = (char16 *) palloc(sizeof(char16));
+
+ memset(new_c16, 0, sizeof(char16));
+ (void) strncpy((char*)new_c16, (char*)arg1, 16);
+ return (char16 *)(strncat((char*)new_c16, (char*)arg2, 16));
+}
+
+text *
+copytext(text *t)
+{
+ /*
+ * VARSIZE is the total size of the struct in bytes.
+ */
+ text *new_t = (text *) palloc(VARSIZE(t));
+
+ memset(new_t, 0, VARSIZE(t));
+
+ VARSIZE(new_t) = VARSIZE(t);
+ /*
+ * VARDATA is a pointer to the data region of the struct.
+ */
+ memcpy((void *) VARDATA(new_t), /* destination */
+ (void *) VARDATA(t), /* source */
+ VARSIZE(t)-VARHDRSZ); /* how many bytes */
+
+ return(new_t);
+}
+
+bool
+c_overpaid(TUPLE t, /* the current instance of EMP */
+ int4 limit)
+{
+ bool isnull = false;
+ int4 salary;
+
+ salary = (int4) GetAttributeByName(t, "salary", &isnull);
+
+ if (isnull)
+ return (false);
+ return(salary > limit);
+}