mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-17 19:30:00 +08:00
Attached is a patch for contrib/tablefunc. It fixes two issues raised by
Lars Boegild Thomsen (full email below) and also corrects the regression expected output for a recent backend message adjustment. Please apply. Joe Conway
This commit is contained in:
parent
04b40923d6
commit
08c33c426b
@ -127,7 +127,7 @@ SELECT * FROM crosstab('SELECT rowid, attribute, val FROM ct where rowclass = ''
|
||||
-- hash based crosstab
|
||||
--
|
||||
create table cth(id serial, rowid text, rowdt timestamp, attribute text, val text);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "cth_id_seq" for SERIAL column "cth.id"
|
||||
NOTICE: CREATE TABLE will create implicit sequence "cth_id_seq" for "serial" column "cth.id"
|
||||
insert into cth values(DEFAULT,'test1','01 March 2003','temperature','42');
|
||||
insert into cth values(DEFAULT,'test1','01 March 2003','test_result','PASS');
|
||||
-- the next line is intentionally left commented and is therefore a "missing" attribute
|
||||
|
@ -1295,56 +1295,19 @@ build_tuplestore_recursively(char *key_fld,
|
||||
int ret;
|
||||
int proc;
|
||||
int serial_column;
|
||||
|
||||
if (max_depth > 0 && level > max_depth)
|
||||
return tupstore;
|
||||
|
||||
/* Build initial sql statement */
|
||||
if (!show_serial)
|
||||
{
|
||||
appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL",
|
||||
key_fld,
|
||||
parent_key_fld,
|
||||
relname,
|
||||
parent_key_fld,
|
||||
start_with,
|
||||
key_fld);
|
||||
serial_column = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL ORDER BY %s",
|
||||
key_fld,
|
||||
parent_key_fld,
|
||||
relname,
|
||||
parent_key_fld,
|
||||
start_with,
|
||||
key_fld,
|
||||
orderby_fld);
|
||||
serial_column = 1;
|
||||
}
|
||||
|
||||
/* Retrieve the desired rows */
|
||||
ret = SPI_exec(sql->data, 0);
|
||||
proc = SPI_processed;
|
||||
|
||||
/* Check for qualifying tuples */
|
||||
if ((ret == SPI_OK_SELECT) && (proc > 0))
|
||||
{
|
||||
HeapTuple tuple;
|
||||
HeapTuple spi_tuple;
|
||||
SPITupleTable *tuptable = SPI_tuptable;
|
||||
TupleDesc spi_tupdesc = tuptable->tupdesc;
|
||||
int i;
|
||||
StringInfo branchstr = NULL;
|
||||
StringInfo chk_branchstr = NULL;
|
||||
StringInfo chk_current_key = NULL;
|
||||
char **values;
|
||||
char *current_key;
|
||||
char *current_key_parent;
|
||||
char current_level[INT32_STRLEN];
|
||||
char serial_str[INT32_STRLEN];
|
||||
char *current_branch;
|
||||
char **values;
|
||||
StringInfo branchstr = NULL;
|
||||
StringInfo chk_branchstr = NULL;
|
||||
StringInfo chk_current_key = NULL;
|
||||
HeapTuple tuple;
|
||||
|
||||
if (max_depth > 0 && level > max_depth)
|
||||
return tupstore;
|
||||
|
||||
/* start a new branch */
|
||||
branchstr = makeStringInfo();
|
||||
@ -1353,6 +1316,31 @@ build_tuplestore_recursively(char *key_fld,
|
||||
chk_branchstr = makeStringInfo();
|
||||
chk_current_key = makeStringInfo();
|
||||
|
||||
/* Build initial sql statement */
|
||||
if (!show_serial)
|
||||
{
|
||||
appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL AND %s <> %s",
|
||||
key_fld,
|
||||
parent_key_fld,
|
||||
relname,
|
||||
parent_key_fld,
|
||||
start_with,
|
||||
key_fld, key_fld, parent_key_fld);
|
||||
serial_column = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL AND %s <> %s ORDER BY %s",
|
||||
key_fld,
|
||||
parent_key_fld,
|
||||
relname,
|
||||
parent_key_fld,
|
||||
start_with,
|
||||
key_fld, key_fld, parent_key_fld,
|
||||
orderby_fld);
|
||||
serial_column = 1;
|
||||
}
|
||||
|
||||
if (show_branch)
|
||||
values = (char **) palloc((CONNECTBY_NCOLS + serial_column) * sizeof(char *));
|
||||
else
|
||||
@ -1361,19 +1349,6 @@ build_tuplestore_recursively(char *key_fld,
|
||||
/* First time through, do a little setup */
|
||||
if (level == 0)
|
||||
{
|
||||
/*
|
||||
* Check that return tupdesc is compatible with the one we got
|
||||
* from the query, but only at level 0 -- no need to check
|
||||
* more than once
|
||||
*/
|
||||
|
||||
if (!compatConnectbyTupleDescs(tupdesc, spi_tupdesc))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("invalid return type"),
|
||||
errdetail("Return and SQL tuple descriptions are " \
|
||||
"incompatible.")));
|
||||
|
||||
/* root value is the one we initially start with */
|
||||
values[0] = start_with;
|
||||
|
||||
@ -1414,6 +1389,35 @@ build_tuplestore_recursively(char *key_fld,
|
||||
level++;
|
||||
}
|
||||
|
||||
/* Retrieve the desired rows */
|
||||
ret = SPI_exec(sql->data, 0);
|
||||
proc = SPI_processed;
|
||||
|
||||
/* Check for qualifying tuples */
|
||||
if ((ret == SPI_OK_SELECT) && (proc > 0))
|
||||
{
|
||||
HeapTuple spi_tuple;
|
||||
SPITupleTable *tuptable = SPI_tuptable;
|
||||
TupleDesc spi_tupdesc = tuptable->tupdesc;
|
||||
int i;
|
||||
|
||||
/* First time through, do a little more setup */
|
||||
if (level == 0)
|
||||
{
|
||||
/*
|
||||
* Check that return tupdesc is compatible with the one we got
|
||||
* from the query, but only at level 0 -- no need to check
|
||||
* more than once
|
||||
*/
|
||||
|
||||
if (!compatConnectbyTupleDescs(tupdesc, spi_tupdesc))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("invalid return type"),
|
||||
errdetail("Return and SQL tuple descriptions are " \
|
||||
"incompatible.")));
|
||||
}
|
||||
|
||||
for (i = 0; i < proc; i++)
|
||||
{
|
||||
/* initialize branch for this pass */
|
||||
|
Loading…
Reference in New Issue
Block a user