diff options
author | Marc G. Fournier <scrappy@hub.org> | 1996-07-09 06:22:35 +0000 |
---|---|---|
committer | Marc G. Fournier <scrappy@hub.org> | 1996-07-09 06:22:35 +0000 |
commit | d31084e9d1118b25fd16580d9d8c2924b5740dff (patch) | |
tree | 3179e66307d54df9c7b966543550e601eb55e668 /src/tutorial/C-code | |
download | postgresql-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.c | 64 | ||||
-rw-r--r-- | src/tutorial/C-code/complex.c | 150 | ||||
-rw-r--r-- | src/tutorial/C-code/funcs.c | 56 |
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); +} |