Header And Logo

PostgreSQL
| The world's most advanced open source database.

funcs_new.c

Go to the documentation of this file.
00001 /* src/tutorial/funcs_new.c */
00002 
00003 /******************************************************************************
00004   These are user-defined functions that can be bound to a Postgres backend
00005   and called by Postgres to execute SQL functions of the same name.
00006 
00007   The calling format for these functions is defined by the CREATE FUNCTION
00008   SQL statement that binds them to the backend.
00009 
00010   NOTE: this file shows examples of "new style" function call conventions.
00011   See funcs.c for examples of "old style".
00012 *****************************************************************************/
00013 
00014 #include "postgres.h"           /* general Postgres declarations */
00015 
00016 #include "executor/executor.h"  /* for GetAttributeByName() */
00017 #include "utils/geo_decls.h"    /* for point type */
00018 
00019 
00020 PG_MODULE_MAGIC;
00021 
00022 /* These prototypes just prevent possible warnings from gcc. */
00023 
00024 Datum       add_one(PG_FUNCTION_ARGS);
00025 Datum       add_one_float8(PG_FUNCTION_ARGS);
00026 Datum       makepoint(PG_FUNCTION_ARGS);
00027 Datum       copytext(PG_FUNCTION_ARGS);
00028 Datum       concat_text(PG_FUNCTION_ARGS);
00029 Datum       c_overpaid(PG_FUNCTION_ARGS);
00030 
00031 
00032 /* By Value */
00033 
00034 PG_FUNCTION_INFO_V1(add_one);
00035 
00036 Datum
00037 add_one(PG_FUNCTION_ARGS)
00038 {
00039     int32       arg = PG_GETARG_INT32(0);
00040 
00041     PG_RETURN_INT32(arg + 1);
00042 }
00043 
00044 /* By Reference, Fixed Length */
00045 
00046 PG_FUNCTION_INFO_V1(add_one_float8);
00047 
00048 Datum
00049 add_one_float8(PG_FUNCTION_ARGS)
00050 {
00051     /* The macros for FLOAT8 hide its pass-by-reference nature */
00052     float8      arg = PG_GETARG_FLOAT8(0);
00053 
00054     PG_RETURN_FLOAT8(arg + 1.0);
00055 }
00056 
00057 PG_FUNCTION_INFO_V1(makepoint);
00058 
00059 Datum
00060 makepoint(PG_FUNCTION_ARGS)
00061 {
00062     Point      *pointx = PG_GETARG_POINT_P(0);
00063     Point      *pointy = PG_GETARG_POINT_P(1);
00064     Point      *new_point = (Point *) palloc(sizeof(Point));
00065 
00066     new_point->x = pointx->x;
00067     new_point->y = pointy->y;
00068 
00069     PG_RETURN_POINT_P(new_point);
00070 }
00071 
00072 /* By Reference, Variable Length */
00073 
00074 PG_FUNCTION_INFO_V1(copytext);
00075 
00076 Datum
00077 copytext(PG_FUNCTION_ARGS)
00078 {
00079     text       *t = PG_GETARG_TEXT_P(0);
00080 
00081     /*
00082      * VARSIZE is the total size of the struct in bytes.
00083      */
00084     text       *new_t = (text *) palloc(VARSIZE(t));
00085 
00086     SET_VARSIZE(new_t, VARSIZE(t));
00087 
00088     /*
00089      * VARDATA is a pointer to the data region of the struct.
00090      */
00091     memcpy((void *) VARDATA(new_t),     /* destination */
00092            (void *) VARDATA(t), /* source */
00093            VARSIZE(t) - VARHDRSZ);      /* how many bytes */
00094     PG_RETURN_TEXT_P(new_t);
00095 }
00096 
00097 PG_FUNCTION_INFO_V1(concat_text);
00098 
00099 Datum
00100 concat_text(PG_FUNCTION_ARGS)
00101 {
00102     text       *arg1 = PG_GETARG_TEXT_P(0);
00103     text       *arg2 = PG_GETARG_TEXT_P(1);
00104     int32       arg1_size = VARSIZE(arg1) - VARHDRSZ;
00105     int32       arg2_size = VARSIZE(arg2) - VARHDRSZ;
00106     int32       new_text_size = arg1_size + arg2_size + VARHDRSZ;
00107     text       *new_text = (text *) palloc(new_text_size);
00108 
00109     SET_VARSIZE(new_text, new_text_size);
00110     memcpy(VARDATA(new_text), VARDATA(arg1), arg1_size);
00111     memcpy(VARDATA(new_text) + arg1_size, VARDATA(arg2), arg2_size);
00112     PG_RETURN_TEXT_P(new_text);
00113 }
00114 
00115 /* Composite types */
00116 
00117 PG_FUNCTION_INFO_V1(c_overpaid);
00118 
00119 Datum
00120 c_overpaid(PG_FUNCTION_ARGS)
00121 {
00122     HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
00123     int32       limit = PG_GETARG_INT32(1);
00124     bool        isnull;
00125     int32       salary;
00126 
00127     salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
00128     if (isnull)
00129         PG_RETURN_BOOL(false);
00130 
00131     /*
00132      * Alternatively, we might prefer to do PG_RETURN_NULL() for null salary
00133      */
00134 
00135     PG_RETURN_BOOL(salary > limit);
00136 }