#include "postgres.h"#include <float.h>#include <math.h>#include "access/transam.h"#include "access/xact.h"#include "catalog/pg_type.h"#include "commands/sequence.h"#include "commands/trigger.h"#include "executor/executor.h"#include "executor/spi.h"#include "utils/builtins.h"#include "utils/geo_decls.h"#include "utils/rel.h"
Go to the source code of this file.
Data Structures | |
| struct | WIDGET |
Defines | |
| #define | P_MAXDIG 12 |
| #define | LDELIM '(' |
| #define | RDELIM ')' |
| #define | DELIM ',' |
| #define | NARGS 3 |
| #define | TTDUMMY_INFINITY 999999 |
Functions | |
| Datum | regress_dist_ptpath (PG_FUNCTION_ARGS) |
| Datum | regress_path_dist (PG_FUNCTION_ARGS) |
| PATH * | poly2path (POLYGON *poly) |
| Datum | interpt_pp (PG_FUNCTION_ARGS) |
| void | regress_lseg_construct (LSEG *lseg, Point *pt1, Point *pt2) |
| Datum | overpaid (PG_FUNCTION_ARGS) |
| Datum | boxarea (PG_FUNCTION_ARGS) |
| char * | reverse_name (char *string) |
| int | oldstyle_length (int n, text *t) |
| Datum | int44in (PG_FUNCTION_ARGS) |
| Datum | int44out (PG_FUNCTION_ARGS) |
| PG_FUNCTION_INFO_V1 (regress_dist_ptpath) | |
| PG_FUNCTION_INFO_V1 (regress_path_dist) | |
| PG_FUNCTION_INFO_V1 (interpt_pp) | |
| PG_FUNCTION_INFO_V1 (overpaid) | |
| WIDGET * | widget_in (char *str) |
| char * | widget_out (WIDGET *widget) |
| Datum | pt_in_widget (PG_FUNCTION_ARGS) |
| PG_FUNCTION_INFO_V1 (pt_in_widget) | |
| PG_FUNCTION_INFO_V1 (boxarea) | |
| Datum | funny_dup17 (PG_FUNCTION_ARGS) |
| PG_FUNCTION_INFO_V1 (funny_dup17) | |
| Datum | ttdummy (PG_FUNCTION_ARGS) |
| Datum | set_ttdummy (PG_FUNCTION_ARGS) |
| PG_FUNCTION_INFO_V1 (ttdummy) | |
| PG_FUNCTION_INFO_V1 (set_ttdummy) | |
| PG_FUNCTION_INFO_V1 (int44in) | |
| PG_FUNCTION_INFO_V1 (int44out) | |
Variables | |
| PG_MODULE_MAGIC | |
| static TransactionId | fd17b_xid = InvalidTransactionId |
| static TransactionId | fd17a_xid = InvalidTransactionId |
| static int | fd17b_level = 0 |
| static int | fd17a_level = 0 |
| static bool | fd17b_recursion = true |
| static bool | fd17a_recursion = true |
| static SPIPlanPtr | splan = NULL |
| static bool | ttoff = false |
| #define LDELIM '(' |
Definition at line 23 of file regress.c.
Referenced by widget_in().
| #define NARGS 3 |
Definition at line 236 of file regress.c.
Referenced by widget_in().
| #define P_MAXDIG 12 |
Definition at line 22 of file regress.c.
Referenced by poly2path().
| #define RDELIM ')' |
Definition at line 24 of file regress.c.
Referenced by poly2path().
| Datum boxarea | ( | PG_FUNCTION_ARGS | ) |
Definition at line 292 of file regress.c.
References Abs, BOX::high, BOX::low, PG_GETARG_BOX_P, PG_RETURN_FLOAT8, Point::x, and Point::y.
| Datum funny_dup17 | ( | PG_FUNCTION_ARGS | ) |
Definition at line 348 of file regress.c.
References CALLED_AS_TRIGGER, CStringGetDatum, DatumGetInt32, DEBUG4, DirectFunctionCall1, elog, ERROR, fd17a_level, fd17a_recursion, fd17a_xid, fd17b_level, fd17b_recursion, fd17b_xid, GetCurrentTransactionId(), int4in(), NAMEDATALEN, palloc(), PointerGetDatum, RelationData::rd_att, SPI_connect(), SPI_exec(), SPI_finish(), SPI_fname(), SPI_getrelname(), SPI_gettype(), SPI_getvalue(), SPI_processed, SPI_tuptable, TriggerData::tg_event, TriggerData::tg_relation, TriggerData::tg_trigtuple, TransactionIdIsCurrentTransactionId(), TRIGGER_FIRED_BEFORE, SPITupleTable::tupdesc, and SPITupleTable::vals.
{
TriggerData *trigdata = (TriggerData *) fcinfo->context;
TransactionId *xid;
int *level;
bool *recursion;
Relation rel;
TupleDesc tupdesc;
HeapTuple tuple;
char *query,
*fieldval,
*fieldtype;
char *when;
int inserted;
int selected = 0;
int ret;
if (!CALLED_AS_TRIGGER(fcinfo))
elog(ERROR, "funny_dup17: not fired by trigger manager");
tuple = trigdata->tg_trigtuple;
rel = trigdata->tg_relation;
tupdesc = rel->rd_att;
if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
{
xid = &fd17b_xid;
level = &fd17b_level;
recursion = &fd17b_recursion;
when = "BEFORE";
}
else
{
xid = &fd17a_xid;
level = &fd17a_level;
recursion = &fd17a_recursion;
when = "AFTER ";
}
if (!TransactionIdIsCurrentTransactionId(*xid))
{
*xid = GetCurrentTransactionId();
*level = 0;
*recursion = true;
}
if (*level == 17)
{
*recursion = false;
return PointerGetDatum(tuple);
}
if (!(*recursion))
return PointerGetDatum(tuple);
(*level)++;
SPI_connect();
fieldval = SPI_getvalue(tuple, tupdesc, 1);
fieldtype = SPI_gettype(tupdesc, 1);
query = (char *) palloc(100 + NAMEDATALEN * 3 +
strlen(fieldval) + strlen(fieldtype));
sprintf(query, "insert into %s select * from %s where %s = '%s'::%s",
SPI_getrelname(rel), SPI_getrelname(rel),
SPI_fname(tupdesc, 1),
fieldval, fieldtype);
if ((ret = SPI_exec(query, 0)) < 0)
elog(ERROR, "funny_dup17 (fired %s) on level %3d: SPI_exec (insert ...) returned %d",
when, *level, ret);
inserted = SPI_processed;
sprintf(query, "select count (*) from %s where %s = '%s'::%s",
SPI_getrelname(rel),
SPI_fname(tupdesc, 1),
fieldval, fieldtype);
if ((ret = SPI_exec(query, 0)) < 0)
elog(ERROR, "funny_dup17 (fired %s) on level %3d: SPI_exec (select ...) returned %d",
when, *level, ret);
if (SPI_processed > 0)
{
selected = DatumGetInt32(DirectFunctionCall1(int4in,
CStringGetDatum(SPI_getvalue(
SPI_tuptable->vals[0],
SPI_tuptable->tupdesc,
1
))));
}
elog(DEBUG4, "funny_dup17 (fired %s) on level %3d: %d/%d tuples inserted/selected",
when, *level, inserted, selected);
SPI_finish();
(*level)--;
if (*level == 0)
*xid = InvalidTransactionId;
return PointerGetDatum(tuple);
}
| Datum int44in | ( | PG_FUNCTION_ARGS | ) |
Definition at line 697 of file regress.c.
References i, palloc(), PG_GETARG_CSTRING, and PG_RETURN_POINTER.
{
char *input_string = PG_GETARG_CSTRING(0);
int32 *result = (int32 *) palloc(4 * sizeof(int32));
int i;
i = sscanf(input_string,
"%d, %d, %d, %d",
&result[0],
&result[1],
&result[2],
&result[3]);
while (i < 4)
result[i++] = 0;
PG_RETURN_POINTER(result);
}
| Datum int44out | ( | PG_FUNCTION_ARGS | ) |
Definition at line 721 of file regress.c.
References i, palloc(), PG_GETARG_POINTER, pg_ltoa(), and PG_RETURN_CSTRING.
{
int32 *an_array = (int32 *) PG_GETARG_POINTER(0);
char *result = (char *) palloc(16 * 4); /* Allow 14 digits +
* sign */
int i;
char *walk;
walk = result;
for (i = 0; i < 4; i++)
{
pg_ltoa(an_array[i], walk);
while (*++walk != '\0')
;
*walk++ = ' ';
}
*--walk = '\0';
PG_RETURN_CSTRING(result);
}
| Datum interpt_pp | ( | PG_FUNCTION_ARGS | ) |
Definition at line 156 of file regress.c.
References DatumGetBool, DirectFunctionCall2, i, lseg_interpt(), lseg_intersect(), LsegPGetDatum, PATH::npts, PATH::p, PG_GETARG_PATH_P, PG_RETURN_DATUM, PG_RETURN_NULL, and regress_lseg_construct().
{
PATH *p1 = PG_GETARG_PATH_P(0);
PATH *p2 = PG_GETARG_PATH_P(1);
int i,
j;
LSEG seg1,
seg2;
bool found; /* We've found the intersection */
found = false; /* Haven't found it yet */
for (i = 0; i < p1->npts - 1 && !found; i++)
{
regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);
for (j = 0; j < p2->npts - 1 && !found; j++)
{
regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);
if (DatumGetBool(DirectFunctionCall2(lseg_intersect,
LsegPGetDatum(&seg1),
LsegPGetDatum(&seg2))))
found = true;
}
}
if (!found)
PG_RETURN_NULL();
/*
* Note: DirectFunctionCall2 will kick out an error if lseg_interpt()
* returns NULL, but that should be impossible since we know the two
* segments intersect.
*/
PG_RETURN_DATUM(DirectFunctionCall2(lseg_interpt,
LsegPGetDatum(&seg1),
LsegPGetDatum(&seg2)));
}
| int oldstyle_length | ( | int | n, | |
| text * | t | |||
| ) |
| Datum overpaid | ( | PG_FUNCTION_ARGS | ) |
Definition at line 209 of file regress.c.
References DatumGetInt32, GetAttributeByName(), PG_GETARG_HEAPTUPLEHEADER, PG_RETURN_BOOL, and PG_RETURN_NULL.
{
HeapTupleHeader tuple = PG_GETARG_HEAPTUPLEHEADER(0);
bool isnull;
int32 salary;
salary = DatumGetInt32(GetAttributeByName(tuple, "salary", &isnull));
if (isnull)
PG_RETURN_NULL();
PG_RETURN_BOOL(salary > 699);
}
| PG_FUNCTION_INFO_V1 | ( | funny_dup17 | ) |
| PG_FUNCTION_INFO_V1 | ( | boxarea | ) |
| PG_FUNCTION_INFO_V1 | ( | pt_in_widget | ) |
| PG_FUNCTION_INFO_V1 | ( | set_ttdummy | ) |
| PG_FUNCTION_INFO_V1 | ( | int44out | ) |
| PG_FUNCTION_INFO_V1 | ( | int44in | ) |
| PG_FUNCTION_INFO_V1 | ( | regress_dist_ptpath | ) |
| PG_FUNCTION_INFO_V1 | ( | overpaid | ) |
| PG_FUNCTION_INFO_V1 | ( | ttdummy | ) |
| PG_FUNCTION_INFO_V1 | ( | regress_path_dist | ) |
| PG_FUNCTION_INFO_V1 | ( | interpt_pp | ) |
Definition at line 131 of file regress.c.
References buf, CStringGetDatum, DatumGetPathP, DirectFunctionCall1, i, POLYGON::npts, output(), POLYGON::p, P_MAXDIG, palloc(), path_in(), RDELIM, snprintf(), Point::x, and Point::y.
{
int i;
char *output = (char *) palloc(2 * (P_MAXDIG + 1) * poly->npts + 64);
char buf[2 * (P_MAXDIG) + 20];
sprintf(output, "(1, %*d", P_MAXDIG, poly->npts);
for (i = 0; i < poly->npts; i++)
{
snprintf(buf, sizeof(buf), ",%*g,%*g",
P_MAXDIG, poly->p[i].x, P_MAXDIG, poly->p[i].y);
strcat(output, buf);
}
snprintf(buf, sizeof(buf), "%c", RDELIM);
strcat(output, buf);
return DatumGetPathP(DirectFunctionCall1(path_in,
CStringGetDatum(output)));
}
| Datum pt_in_widget | ( | PG_FUNCTION_ARGS | ) |
Definition at line 281 of file regress.c.
References WIDGET::center, PG_GETARG_POINT_P, PG_GETARG_POINTER, PG_RETURN_BOOL, point_dt(), and WIDGET::radius.
{
Point *point = PG_GETARG_POINT_P(0);
WIDGET *widget = (WIDGET *) PG_GETARG_POINTER(1);
PG_RETURN_BOOL(point_dt(point, &widget->center) < widget->radius);
}
| Datum regress_dist_ptpath | ( | PG_FUNCTION_ARGS | ) |
Definition at line 50 of file regress.c.
References Assert, DatumGetFloat8, DirectFunctionCall2, dist_ps(), i, LsegPGetDatum, PATH::npts, PATH::p, PG_GETARG_PATH_P, PG_GETARG_POINT_P, PG_RETURN_FLOAT8, PG_RETURN_NULL, point_dt(), PointPGetDatum, and regress_lseg_construct().
{
Point *pt = PG_GETARG_POINT_P(0);
PATH *path = PG_GETARG_PATH_P(1);
float8 result = 0.0; /* keep compiler quiet */
float8 tmp;
int i;
LSEG lseg;
switch (path->npts)
{
case 0:
PG_RETURN_NULL();
case 1:
result = point_dt(pt, &path->p[0]);
break;
default:
/*
* the distance from a point to a path is the smallest distance
* from the point to any of its constituent segments.
*/
Assert(path->npts > 1);
for (i = 0; i < path->npts - 1; ++i)
{
regress_lseg_construct(&lseg, &path->p[i], &path->p[i + 1]);
tmp = DatumGetFloat8(DirectFunctionCall2(dist_ps,
PointPGetDatum(pt),
LsegPGetDatum(&lseg)));
if (i == 0 || tmp < result)
result = tmp;
}
break;
}
PG_RETURN_FLOAT8(result);
}
Definition at line 197 of file regress.c.
References LSEG::m, LSEG::p, point_sl(), Point::x, and Point::y.
Referenced by interpt_pp(), regress_dist_ptpath(), and regress_path_dist().
| Datum regress_path_dist | ( | PG_FUNCTION_ARGS | ) |
Definition at line 94 of file regress.c.
References DatumGetFloat8, DirectFunctionCall2, i, lseg_distance(), LsegPGetDatum, PATH::npts, PATH::p, PG_GETARG_PATH_P, PG_RETURN_FLOAT8, PG_RETURN_NULL, and regress_lseg_construct().
{
PATH *p1 = PG_GETARG_PATH_P(0);
PATH *p2 = PG_GETARG_PATH_P(1);
bool have_min = false;
float8 min = 0.0; /* initialize to keep compiler quiet */
float8 tmp;
int i,
j;
LSEG seg1,
seg2;
for (i = 0; i < p1->npts - 1; i++)
{
for (j = 0; j < p2->npts - 1; j++)
{
regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);
regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);
tmp = DatumGetFloat8(DirectFunctionCall2(lseg_distance,
LsegPGetDatum(&seg1),
LsegPGetDatum(&seg2)));
if (!have_min || tmp < min)
{
min = tmp;
have_min = true;
}
}
}
if (!have_min)
PG_RETURN_NULL();
PG_RETURN_FLOAT8(min);
}
| char * reverse_name | ( | char * | string | ) |
Definition at line 304 of file regress.c.
References i, NAMEDATALEN, and palloc0().
{
int i;
int len;
char *new_string;
new_string = palloc0(NAMEDATALEN);
for (i = 0; i < NAMEDATALEN && string[i]; ++i)
;
if (i == NAMEDATALEN || !string[i])
--i;
len = i;
for (; i >= 0; --i)
new_string[len - i] = string[i];
return new_string;
}
| Datum set_ttdummy | ( | PG_FUNCTION_ARGS | ) |
Definition at line 659 of file regress.c.
References PG_GETARG_INT32, PG_RETURN_INT32, and ttoff.
{
int32 on = PG_GETARG_INT32(0);
if (ttoff) /* OFF currently */
{
if (on == 0)
PG_RETURN_INT32(0);
/* turn ON */
ttoff = false;
PG_RETURN_INT32(0);
}
/* ON currently */
if (on != 0)
PG_RETURN_INT32(1);
/* turn OFF */
ttoff = true;
PG_RETURN_INT32(1);
}
| Datum ttdummy | ( | PG_FUNCTION_ARGS | ) |
Definition at line 466 of file regress.c.
References CALLED_AS_TRIGGER, CStringGetTextDatum, DatumGetInt64, DirectFunctionCall1, elog, ERROR, i, Int32GetDatum, INT4OID, nextval(), NULL, palloc(), pfree(), PointerGetDatum, SPI_connect(), SPI_copytuple(), SPI_execp(), SPI_finish(), SPI_fnumber(), SPI_freetuple(), SPI_getbinval(), SPI_getrelname(), SPI_gettypeid(), SPI_keepplan(), SPI_modifytuple(), SPI_prepare(), SPI_result, TriggerData::tg_event, TriggerData::tg_newtuple, TriggerData::tg_relation, TriggerData::tg_trigger, TriggerData::tg_trigtuple, TRIGGER_FIRED_BEFORE, TRIGGER_FIRED_BY_INSERT, TRIGGER_FIRED_BY_UPDATE, TRIGGER_FIRED_FOR_ROW, TTDUMMY_INFINITY, and ttoff.
{
TriggerData *trigdata = (TriggerData *) fcinfo->context;
Trigger *trigger; /* to get trigger name */
char **args; /* arguments */
int attnum[2]; /* fnumbers of start/stop columns */
Datum oldon,
oldoff;
Datum newon,
newoff;
Datum *cvals; /* column values */
char *cnulls; /* column nulls */
char *relname; /* triggered relation name */
Relation rel; /* triggered relation */
HeapTuple trigtuple;
HeapTuple newtuple = NULL;
HeapTuple rettuple;
TupleDesc tupdesc; /* tuple description */
int natts; /* # of attributes */
bool isnull; /* to know is some column NULL or not */
int ret;
int i;
if (!CALLED_AS_TRIGGER(fcinfo))
elog(ERROR, "ttdummy: not fired by trigger manager");
if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
elog(ERROR, "ttdummy: must be fired for row");
if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
elog(ERROR, "ttdummy: must be fired before event");
if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
elog(ERROR, "ttdummy: cannot process INSERT event");
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
newtuple = trigdata->tg_newtuple;
trigtuple = trigdata->tg_trigtuple;
rel = trigdata->tg_relation;
relname = SPI_getrelname(rel);
/* check if TT is OFF for this relation */
if (ttoff) /* OFF - nothing to do */
{
pfree(relname);
return PointerGetDatum((newtuple != NULL) ? newtuple : trigtuple);
}
trigger = trigdata->tg_trigger;
if (trigger->tgnargs != 2)
elog(ERROR, "ttdummy (%s): invalid (!= 2) number of arguments %d",
relname, trigger->tgnargs);
args = trigger->tgargs;
tupdesc = rel->rd_att;
natts = tupdesc->natts;
for (i = 0; i < 2; i++)
{
attnum[i] = SPI_fnumber(tupdesc, args[i]);
if (attnum[i] < 0)
elog(ERROR, "ttdummy (%s): there is no attribute %s", relname, args[i]);
if (SPI_gettypeid(tupdesc, attnum[i]) != INT4OID)
elog(ERROR, "ttdummy (%s): attributes %s and %s must be of abstime type",
relname, args[0], args[1]);
}
oldon = SPI_getbinval(trigtuple, tupdesc, attnum[0], &isnull);
if (isnull)
elog(ERROR, "ttdummy (%s): %s must be NOT NULL", relname, args[0]);
oldoff = SPI_getbinval(trigtuple, tupdesc, attnum[1], &isnull);
if (isnull)
elog(ERROR, "ttdummy (%s): %s must be NOT NULL", relname, args[1]);
if (newtuple != NULL) /* UPDATE */
{
newon = SPI_getbinval(newtuple, tupdesc, attnum[0], &isnull);
if (isnull)
elog(ERROR, "ttdummy (%s): %s must be NOT NULL", relname, args[0]);
newoff = SPI_getbinval(newtuple, tupdesc, attnum[1], &isnull);
if (isnull)
elog(ERROR, "ttdummy (%s): %s must be NOT NULL", relname, args[1]);
if (oldon != newon || oldoff != newoff)
elog(ERROR, "ttdummy (%s): you cannot change %s and/or %s columns (use set_ttdummy)",
relname, args[0], args[1]);
if (newoff != TTDUMMY_INFINITY)
{
pfree(relname); /* allocated in upper executor context */
return PointerGetDatum(NULL);
}
}
else if (oldoff != TTDUMMY_INFINITY) /* DELETE */
{
pfree(relname);
return PointerGetDatum(NULL);
}
newoff = DirectFunctionCall1(nextval, CStringGetTextDatum("ttdummy_seq"));
/* nextval now returns int64; coerce down to int32 */
newoff = Int32GetDatum((int32) DatumGetInt64(newoff));
/* Connect to SPI manager */
if ((ret = SPI_connect()) < 0)
elog(ERROR, "ttdummy (%s): SPI_connect returned %d", relname, ret);
/* Fetch tuple values and nulls */
cvals = (Datum *) palloc(natts * sizeof(Datum));
cnulls = (char *) palloc(natts * sizeof(char));
for (i = 0; i < natts; i++)
{
cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple,
tupdesc, i + 1, &isnull);
cnulls[i] = (isnull) ? 'n' : ' ';
}
/* change date column(s) */
if (newtuple) /* UPDATE */
{
cvals[attnum[0] - 1] = newoff; /* start_date eq current date */
cnulls[attnum[0] - 1] = ' ';
cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */
cnulls[attnum[1] - 1] = ' ';
}
else
/* DELETE */
{
cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */
cnulls[attnum[1] - 1] = ' ';
}
/* if there is no plan ... */
if (splan == NULL)
{
SPIPlanPtr pplan;
Oid *ctypes;
char *query;
/* allocate space in preparation */
ctypes = (Oid *) palloc(natts * sizeof(Oid));
query = (char *) palloc(100 + 16 * natts);
/*
* Construct query: INSERT INTO _relation_ VALUES ($1, ...)
*/
sprintf(query, "INSERT INTO %s VALUES (", relname);
for (i = 1; i <= natts; i++)
{
sprintf(query + strlen(query), "$%d%s",
i, (i < natts) ? ", " : ")");
ctypes[i - 1] = SPI_gettypeid(tupdesc, i);
}
/* Prepare plan for query */
pplan = SPI_prepare(query, natts, ctypes);
if (pplan == NULL)
elog(ERROR, "ttdummy (%s): SPI_prepare returned %d", relname, SPI_result);
if (SPI_keepplan(pplan))
elog(ERROR, "ttdummy (%s): SPI_keepplan failed", relname);
splan = pplan;
}
ret = SPI_execp(splan, cvals, cnulls, 0);
if (ret < 0)
elog(ERROR, "ttdummy (%s): SPI_execp returned %d", relname, ret);
/* Tuple to return to upper Executor ... */
if (newtuple) /* UPDATE */
{
HeapTuple tmptuple;
tmptuple = SPI_copytuple(trigtuple);
rettuple = SPI_modifytuple(rel, tmptuple, 1, &(attnum[1]), &newoff, NULL);
SPI_freetuple(tmptuple);
}
else
/* DELETE */
rettuple = trigtuple;
SPI_finish(); /* don't forget say Bye to SPI mgr */
pfree(relname);
return PointerGetDatum(rettuple);
}
| WIDGET * widget_in | ( | char * | str | ) |
Definition at line 239 of file regress.c.
References WIDGET::center, i, LDELIM, NARGS, NULL, palloc(), WIDGET::radius, snprintf(), Point::x, and Point::y.
{
char *p,
*coord[NARGS],
buf2[1000];
int i;
WIDGET *result;
if (str == NULL)
return NULL;
for (i = 0, p = str; *p && i < NARGS && *p != RDELIM; p++)
if (*p == ',' || (*p == LDELIM && !i))
coord[i++] = p + 1;
if (i < NARGS - 1)
return NULL;
result = (WIDGET *) palloc(sizeof(WIDGET));
result->center.x = atof(coord[0]);
result->center.y = atof(coord[1]);
result->radius = atof(coord[2]);
snprintf(buf2, sizeof(buf2), "widget_in: read (%f, %f, %f)\n",
result->center.x, result->center.y, result->radius);
return result;
}
| char * widget_out | ( | WIDGET * | widget | ) |
Definition at line 265 of file regress.c.
References WIDGET::center, NULL, palloc(), WIDGET::radius, Point::x, and Point::y.
int fd17a_level = 0 [static] |
Definition at line 340 of file regress.c.
Referenced by funny_dup17().
bool fd17a_recursion = true [static] |
Definition at line 342 of file regress.c.
Referenced by funny_dup17().
TransactionId fd17a_xid = InvalidTransactionId [static] |
Definition at line 338 of file regress.c.
Referenced by funny_dup17().
int fd17b_level = 0 [static] |
Definition at line 339 of file regress.c.
Referenced by funny_dup17().
bool fd17b_recursion = true [static] |
Definition at line 341 of file regress.c.
Referenced by funny_dup17().
TransactionId fd17b_xid = InvalidTransactionId [static] |
Definition at line 337 of file regress.c.
Referenced by funny_dup17().
SPIPlanPtr splan = NULL [static] |
Definition at line 460 of file regress.c.
Referenced by build_subplan(), ExecReScan(), get_rule_expr(), set_plan_refs(), and SS_process_ctes().
1.7.1