HEAD and 8.0.X.
file1 file2 file3 file4 file5
- 1.1 1.1 1.1 1.1 /--1.1* <-*- TAG
+ 1.1 1.1 1.1 1.1 /--1.1* <-*- TAG
1.2*- 1.2 1.2 -1.2*-
1.3 \- 1.3*- 1.3 / 1.3
1.4 \ 1.4 / 1.4
*indexSelectivity = clauselist_selectivity(root, indexQuals,
- rel->relid, JOIN_INNER);
+ rel->relid, JOIN_INNER);
/*
* Called as a trigger procedure
*/
- TriggerData *trigdata = (TriggerData *) fcinfo->context;
+ TriggerData *trigdata = (TriggerData *) fcinfo->context;
retval = ...
}
Fix many CLUSTER failures (Tom)
Allow ALTER TABLE RENAME works on indexes (Tom)
-Fix plpgsql to handle datetime->timestamp and timespan->interval (Bruce)
+Fix plpgsql to handle datetime->timestamp and timespan->interval (Bruce)
New configure --with-setproctitle switch to use setproctitle() (Marc, Bruce)
Fix the off by one errors in ResultSet from 6.5.3, and more.
jdbc ResultSet fixes (Joseph Shraibman)
Bug Fixes
---------
-Fix text<->float8 and text<->float4 conversion functions(Thomas)
+Fix text<->float8 and text<->float4 conversion functions(Thomas)
Fix for creating tables with mixed-case constraints(Billy)
Change exp()/pow() behavior to generate error on underflow/overflow(Jan)
Fix bug in pg_dump -z
using an axis-crossing algorithm(Thomas)
Add routine to convert circle-box(Thomas)
Merge conflicting operators for different geometric data types(Thomas)
-Replace distance operator "<===>" with "<->"(Thomas)
+Replace distance operator "<===>" with "<->"(Thomas)
Replace "above" operator "!^" with ">^" and "below" operator "!|" with "<^"(Thomas)
Add routines for text trimming on both ends, substring, and string position(Thomas)
Added conversion routines circle(box) and poly(circle)(Thomas)
char(N), varchar(N), date and time.
The following are aliases to existing postgres types:
- smallint -> int2
- integer, int -> int4
- float, real -> float4
+ smallint -> int2
+ integer, int -> int4
+ float, real -> float4
char(N) and varchar(N) are implemented as truncated text types. In
addition, char(N) does blank-padding.
* single-quote (') is used for quoting string literals; '' (in addition to
-
+
The Rule System
Nested Loop
- -> Merge Join
- -> Seq Scan
- -> Sort
- -> Seq Scan on s
- -> Seq Scan
- -> Sort
- -> Seq Scan on shoelace_arrive
- -> Seq Scan on shoelace_data
+ -> Merge Join
+ -> Seq Scan
+ -> Sort
+ -> Seq Scan on s
+ -> Seq Scan
+ -> Sort
+ -> Seq Scan on shoelace_arrive
+ -> Seq Scan on shoelace_data
while omitting the extra range table entry would result in a
Merge Join
- -> Seq Scan
- -> Sort
- -> Seq Scan on s
- -> Seq Scan
- -> Sort
- -> Seq Scan on shoelace_arrive
+ -> Seq Scan
+ -> Sort
+ -> Seq Scan on s
+ -> Seq Scan
+ -> Sort
+ -> Seq Scan on shoelace_arrive
which produces exactly the same entries in the log table. Thus,
Nestloop
- -> Index Scan using comp_hostidx on computer
- -> Index Scan using soft_hostidx on software
+ -> Index Scan using comp_hostidx on computer
+ -> Index Scan using soft_hostidx on software
So there would be not that much difference in speed between
Hash Join
- -> Seq Scan on software
- -> Hash
- -> Index Scan using comp_hostidx on computer
+ -> Seq Scan on software
+ -> Hash
+ -> Index Scan using comp_hostidx on computer
The other possible command is
Nestloop
- -> Index Scan using comp_hostidx on computer
- -> Index Scan using soft_hostidx on software
+ -> Index Scan using comp_hostidx on computer
+ -> Index Scan using soft_hostidx on software
This shows, that the planner does not realize that the
Nestloop
- -> Index Scan using comp_manufidx on computer
- -> Index Scan using soft_hostidx on software
+ -> Index Scan using comp_manufidx on computer
+ -> Index Scan using soft_hostidx on software
In any of these cases, the extra commands from the rule system
*/
if (ret == SPI_OK_SELECT && SPI_processed > 0)
{
- TupleDesc tupdesc = SPI_tuptable->tupdesc;
+ TupleDesc tupdesc = SPI_tuptable->tupdesc;
SPITupleTable *tuptable = SPI_tuptable;
char buf[8192];
int i, j;
for (j = 0; j < proc; j++)
{
- HeapTuple tuple = tuptable->vals[j];
+ HeapTuple tuple = tuptable->vals[j];
- for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++)
+ for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++)
snprintf(buf + strlen (buf), sizeof(buf) - strlen(buf), " %s%s",
SPI_getvalue(tuple, tupdesc, i),
- (i == tupdesc->natts) ? " " : " |");
+ (i == tupdesc->natts) ? " " : " |");
elog (INFO, "EXECQ: %s", buf);
}
}
which expands to
-((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
+((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
If this returns true, then it is safe to cast
- fcinfo->context> to type TriggerData
+ fcinfo->context> to type TriggerData
* and make use of the pointed-to
TriggerData> structure. The function must
not alter the TriggerData>
A pointer to a structure describing the relation that the trigger fired for.
Look at utils/rel.h> for details about
this structure. The most interesting things are
- tg_relation->rd_att> (descriptor of the relation
- tuples) and tg_relation->rd_rel->relname>
+ tg_relation->rd_att> (descriptor of the relation
+ tuples) and tg_relation->rd_rel->relname>
(relation name; the type is not char*> but
NameData>; use
SPI_getrelname(tg_relation)> to get a char*> if you
Datum
trigf(PG_FUNCTION_ARGS)
{
- TriggerData *trigdata = (TriggerData *) fcinfo->context;
+ TriggerData *trigdata = (TriggerData *) fcinfo->context;
TupleDesc tupdesc;
HeapTuple rettuple;
char *when;
elog(ERROR, "trigf: not called by trigger manager");
/* tuple to return to executor */
- if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
- rettuple = trigdata->tg_newtuple;
+ if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
+ rettuple = trigdata->tg_newtuple;
else
- rettuple = trigdata->tg_trigtuple;
+ rettuple = trigdata->tg_trigtuple;
/* check for null values */
- if (!TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)
- && TRIGGER_FIRED_BEFORE(trigdata->tg_event))
+ if (!TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)
+ && TRIGGER_FIRED_BEFORE(trigdata->tg_event))
checknull = true;
- if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
+ if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
when = "before";
else
when = "after ";
- tupdesc = trigdata->tg_relation->rd_att;
+ tupdesc = trigdata->tg_relation->rd_att;
/* connect to SPI manager */
if ((ret = SPI_connect()) < 0)
elog(NOTICE, "trigf (fired %s): SPI_exec returned %d", when, ret);
/* count(*) returns int8, so be careful to convert */
- i = DatumGetInt64(SPI_getbinval(SPI_tuptable->vals[0],
- SPI_tuptable->tupdesc,
+ i = DatumGetInt64(SPI_getbinval(SPI_tuptable->vals[0],
+ SPI_tuptable->tupdesc,
1,
&isnull));
{
Point *new_point = (Point *) palloc(sizeof(Point));
- new_point->x = pointx->x;
- new_point->y = pointy->y;
+ new_point->x = pointx->x;
+ new_point->y = pointy->y;
return new_point;
}
Point *pointy = PG_GETARG_POINT_P(1);
Point *new_point = (Point *) palloc(sizeof(Point));
- new_point->x = pointx->x;
- new_point->y = pointy->y;
+ new_point->x = pointx->x;
+ new_point->y = pointy->y;
PG_RETURN_POINT_P(new_point);
}
if (SRF_IS_FIRSTCALL())
{
funcctx = SRF_FIRSTCALL_INIT();
- oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+ oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
/* One-time setup code appears here: */
user code
if returning composite
funcctx = SRF_FIRSTCALL_INIT();
/* switch to memory context appropriate for multiple function calls */
- oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+ oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
/* total number of tuples to be returned */
funcctx->max_calls = PG_GETARG_UINT32(0);