From f3f7712675abf9310859e4a1ccf6407dc3a3770e Mon Sep 17 00:00:00 2001 From: Marc G. Fournier Date: Sun, 1 Mar 1998 04:51:16 +0000 Subject: Move around files before applying Darren's second patch --- src/tutorial/C-code/Makefile | 18 ---- src/tutorial/C-code/beard.c | 64 --------------- src/tutorial/C-code/complex.c | 186 ------------------------------------------ src/tutorial/C-code/funcs.c | 81 ------------------ src/tutorial/beard.c | 64 +++++++++++++++ src/tutorial/complex.c | 186 ++++++++++++++++++++++++++++++++++++++++++ src/tutorial/funcs.c | 81 ++++++++++++++++++ 7 files changed, 331 insertions(+), 349 deletions(-) delete mode 100644 src/tutorial/C-code/Makefile delete mode 100644 src/tutorial/C-code/beard.c delete mode 100644 src/tutorial/C-code/complex.c delete mode 100644 src/tutorial/C-code/funcs.c create mode 100644 src/tutorial/beard.c create mode 100644 src/tutorial/complex.c create mode 100644 src/tutorial/funcs.c (limited to 'src/tutorial') diff --git a/src/tutorial/C-code/Makefile b/src/tutorial/C-code/Makefile deleted file mode 100644 index ec1fa1f21f5..00000000000 --- a/src/tutorial/C-code/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -SRCDIR= ../.. -include ../../Makefile.global - -CFLAGS+= -I../../include -I$(LIBPQDIR) - -# -# And where libpq goes, so goes the authentication stuff... -# -ifdef KRBVERS -LDFLAGS+= $(KRBLIBS) -CFLAGS+= $(KRBFLAGS) -endif - -all: complex$(DLSUFFIX) funcs$(DLSUFFIX) - -clean: - rm -f complex$(DLSUFFIX) funcs$(DLSUFFIX) - diff --git a/src/tutorial/C-code/beard.c b/src/tutorial/C-code/beard.c deleted file mode 100644 index 6e11ddea856..00000000000 --- a/src/tutorial/C-code/beard.c +++ /dev/null @@ -1,64 +0,0 @@ -/*------------------------------------------------------------------------- - * - * 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.5 1998/01/07 21:07:03 momjian 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(ERROR, "Cannot access picture large object"); - - if (lo_read(pic_fd, (char *) &ihdr, sizeof(ihdr)) != sizeof(ihdr)) - elog(ERROR, "Picture large object corrupted"); - - beardOffset = (ihdr.size / 3) * 2; - - /* - * new large object - */ - if ((beard = lo_creat(INV_MD)) == 0) /* ?? is this right? */ - elog(ERROR, "Cannot create new large object"); - - if ((beard_fd = lo_open(beard, INV_WRITE)) == -1) - elog(ERROR, "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(ERROR, "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 deleted file mode 100644 index e5bea2d1134..00000000000 --- a/src/tutorial/C-code/complex.c +++ /dev/null @@ -1,186 +0,0 @@ -/****************************************************************************** - This file contains routines that can be bound to a Postgres backend and - called by the backend in the process of processing queries. The calling - format for these routines is dictated by Postgres architecture. -******************************************************************************/ - -#include -/* 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; - -/* These prototypes declare the requirements that Postgres places on these - user written functions. -*/ -Complex *complex_in(char *str); -char *complex_out(Complex * complex); -Complex *complex_add(Complex * a, Complex * b); -bool complex_abs_lt(Complex * a, Complex * b); -bool complex_abs_le(Complex * a, Complex * b); -bool complex_abs_eq(Complex * a, Complex * b); -bool complex_abs_ge(Complex * a, Complex * b); -bool complex_abs_gt(Complex * a, Complex * b); -int4 complex_abs_cmp(Complex * a, Complex * b); - - -/***************************************************************************** - * Input/Output functions - *****************************************************************************/ - -Complex * -complex_in(char *str) -{ - double x, - y; - Complex *result; - - if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2) - { - elog(ERROR, "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, "(%g,%g)", 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 (amag < bmag) - return -1; - else if (amag > bmag) - 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(void); -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 deleted file mode 100644 index 71371f51609..00000000000 --- a/src/tutorial/C-code/funcs.c +++ /dev/null @@ -1,81 +0,0 @@ -/****************************************************************************** - These are user-defined functions that can be bound to a Postgres backend - and called by Postgres to execute SQL functions of the same name. - - The calling format for these functions is defined by the CREATE FUNCTION - SQL statement that binds them to the backend. -*****************************************************************************/ - -#include -#include -#include "postgres.h" /* for char16, etc. */ -#include "utils/palloc.h" /* for palloc */ -#include "libpq-fe.h" /* for TUPLE */ -#include "executor/executor.h" /* for GetAttributeByName() */ - -/* The following prototypes declare what we assume the user declares to - Postgres in his CREATE FUNCTION statement. -*/ - -int add_one(int arg); -char16 *concat16(char16 *arg1, char16 *arg2); -text *copytext(text *t); - -bool -c_overpaid(TUPLE t, /* the current instance of EMP */ - int4 limit); - - - -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)); - 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); -} diff --git a/src/tutorial/beard.c b/src/tutorial/beard.c new file mode 100644 index 00000000000..9207f04d394 --- /dev/null +++ b/src/tutorial/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/Attic/beard.c,v 1.1 1998/03/01 04:51:01 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(ERROR, "Cannot access picture large object"); + + if (lo_read(pic_fd, (char *) &ihdr, sizeof(ihdr)) != sizeof(ihdr)) + elog(ERROR, "Picture large object corrupted"); + + beardOffset = (ihdr.size / 3) * 2; + + /* + * new large object + */ + if ((beard = lo_creat(INV_MD)) == 0) /* ?? is this right? */ + elog(ERROR, "Cannot create new large object"); + + if ((beard_fd = lo_open(beard, INV_WRITE)) == -1) + elog(ERROR, "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(ERROR, "error while writing large object"); + } + + lo_close(pic_fd); + lo_close(beard_fd); + + return beard; +} diff --git a/src/tutorial/complex.c b/src/tutorial/complex.c new file mode 100644 index 00000000000..e5bea2d1134 --- /dev/null +++ b/src/tutorial/complex.c @@ -0,0 +1,186 @@ +/****************************************************************************** + This file contains routines that can be bound to a Postgres backend and + called by the backend in the process of processing queries. The calling + format for these routines is dictated by Postgres architecture. +******************************************************************************/ + +#include +/* 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; + +/* These prototypes declare the requirements that Postgres places on these + user written functions. +*/ +Complex *complex_in(char *str); +char *complex_out(Complex * complex); +Complex *complex_add(Complex * a, Complex * b); +bool complex_abs_lt(Complex * a, Complex * b); +bool complex_abs_le(Complex * a, Complex * b); +bool complex_abs_eq(Complex * a, Complex * b); +bool complex_abs_ge(Complex * a, Complex * b); +bool complex_abs_gt(Complex * a, Complex * b); +int4 complex_abs_cmp(Complex * a, Complex * b); + + +/***************************************************************************** + * Input/Output functions + *****************************************************************************/ + +Complex * +complex_in(char *str) +{ + double x, + y; + Complex *result; + + if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2) + { + elog(ERROR, "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, "(%g,%g)", 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 (amag < bmag) + return -1; + else if (amag > bmag) + 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(void); +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/funcs.c b/src/tutorial/funcs.c new file mode 100644 index 00000000000..71371f51609 --- /dev/null +++ b/src/tutorial/funcs.c @@ -0,0 +1,81 @@ +/****************************************************************************** + These are user-defined functions that can be bound to a Postgres backend + and called by Postgres to execute SQL functions of the same name. + + The calling format for these functions is defined by the CREATE FUNCTION + SQL statement that binds them to the backend. +*****************************************************************************/ + +#include +#include +#include "postgres.h" /* for char16, etc. */ +#include "utils/palloc.h" /* for palloc */ +#include "libpq-fe.h" /* for TUPLE */ +#include "executor/executor.h" /* for GetAttributeByName() */ + +/* The following prototypes declare what we assume the user declares to + Postgres in his CREATE FUNCTION statement. +*/ + +int add_one(int arg); +char16 *concat16(char16 *arg1, char16 *arg2); +text *copytext(text *t); + +bool +c_overpaid(TUPLE t, /* the current instance of EMP */ + int4 limit); + + + +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)); + 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); +} -- cgit v1.2.3