Skip to content

Commit 08c33c4

Browse files
committed
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
1 parent 04b4092 commit 08c33c4

File tree

2 files changed

+71
-67
lines changed

2 files changed

+71
-67
lines changed

contrib/tablefunc/expected/tablefunc.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ SELECT * FROM crosstab('SELECT rowid, attribute, val FROM ct where rowclass = ''
127127
-- hash based crosstab
128128
--
129129
create table cth(id serial, rowid text, rowdt timestamp, attribute text, val text);
130-
NOTICE: CREATE TABLE will create implicit sequence "cth_id_seq" for SERIAL column "cth.id"
130+
NOTICE: CREATE TABLE will create implicit sequence "cth_id_seq" for "serial" column "cth.id"
131131
insert into cth values(DEFAULT,'test1','01 March 2003','temperature','42');
132132
insert into cth values(DEFAULT,'test1','01 March 2003','test_result','PASS');
133133
-- the next line is intentionally left commented and is therefore a "missing" attribute

contrib/tablefunc/tablefunc.c

Lines changed: 70 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,70 +1295,113 @@ build_tuplestore_recursively(char *key_fld,
12951295
int ret;
12961296
int proc;
12971297
int serial_column;
1298+
StringInfo branchstr = NULL;
1299+
StringInfo chk_branchstr = NULL;
1300+
StringInfo chk_current_key = NULL;
1301+
char **values;
1302+
char *current_key;
1303+
char *current_key_parent;
1304+
char current_level[INT32_STRLEN];
1305+
char serial_str[INT32_STRLEN];
1306+
char *current_branch;
1307+
HeapTuple tuple;
12981308

12991309
if (max_depth > 0 && level > max_depth)
13001310
return tupstore;
13011311

1312+
/* start a new branch */
1313+
branchstr = makeStringInfo();
1314+
1315+
/* need these to check for recursion */
1316+
chk_branchstr = makeStringInfo();
1317+
chk_current_key = makeStringInfo();
1318+
13021319
/* Build initial sql statement */
13031320
if (!show_serial)
13041321
{
1305-
appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL",
1322+
appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL AND %s <> %s",
13061323
key_fld,
13071324
parent_key_fld,
13081325
relname,
13091326
parent_key_fld,
13101327
start_with,
1311-
key_fld);
1328+
key_fld, key_fld, parent_key_fld);
13121329
serial_column = 0;
13131330
}
13141331
else
13151332
{
1316-
appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL ORDER BY %s",
1333+
appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL AND %s <> %s ORDER BY %s",
13171334
key_fld,
13181335
parent_key_fld,
13191336
relname,
13201337
parent_key_fld,
13211338
start_with,
1322-
key_fld,
1339+
key_fld, key_fld, parent_key_fld,
13231340
orderby_fld);
13241341
serial_column = 1;
13251342
}
13261343

1344+
if (show_branch)
1345+
values = (char **) palloc((CONNECTBY_NCOLS + serial_column) * sizeof(char *));
1346+
else
1347+
values = (char **) palloc((CONNECTBY_NCOLS_NOBRANCH + serial_column) * sizeof(char *));
1348+
1349+
/* First time through, do a little setup */
1350+
if (level == 0)
1351+
{
1352+
/* root value is the one we initially start with */
1353+
values[0] = start_with;
1354+
1355+
/* root value has no parent */
1356+
values[1] = NULL;
1357+
1358+
/* root level is 0 */
1359+
sprintf(current_level, "%d", level);
1360+
values[2] = current_level;
1361+
1362+
/* root branch is just starting root value */
1363+
if (show_branch)
1364+
values[3] = start_with;
1365+
1366+
/* root starts the serial with 1 */
1367+
if (show_serial)
1368+
{
1369+
sprintf(serial_str, "%d", (*serial)++);
1370+
if (show_branch)
1371+
values[4] = serial_str;
1372+
else
1373+
values[3] = serial_str;
1374+
}
1375+
1376+
/* construct the tuple */
1377+
tuple = BuildTupleFromCStrings(attinmeta, values);
1378+
1379+
/* switch to long lived context while storing the tuple */
1380+
oldcontext = MemoryContextSwitchTo(per_query_ctx);
1381+
1382+
/* now store it */
1383+
tuplestore_puttuple(tupstore, tuple);
1384+
1385+
/* now reset the context */
1386+
MemoryContextSwitchTo(oldcontext);
1387+
1388+
/* increment level */
1389+
level++;
1390+
}
1391+
13271392
/* Retrieve the desired rows */
13281393
ret = SPI_exec(sql->data, 0);
13291394
proc = SPI_processed;
13301395

13311396
/* Check for qualifying tuples */
13321397
if ((ret == SPI_OK_SELECT) && (proc > 0))
13331398
{
1334-
HeapTuple tuple;
13351399
HeapTuple spi_tuple;
13361400
SPITupleTable *tuptable = SPI_tuptable;
13371401
TupleDesc spi_tupdesc = tuptable->tupdesc;
13381402
int i;
1339-
char *current_key;
1340-
char *current_key_parent;
1341-
char current_level[INT32_STRLEN];
1342-
char serial_str[INT32_STRLEN];
1343-
char *current_branch;
1344-
char **values;
1345-
StringInfo branchstr = NULL;
1346-
StringInfo chk_branchstr = NULL;
1347-
StringInfo chk_current_key = NULL;
1348-
1349-
/* start a new branch */
1350-
branchstr = makeStringInfo();
13511403

1352-
/* need these to check for recursion */
1353-
chk_branchstr = makeStringInfo();
1354-
chk_current_key = makeStringInfo();
1355-
1356-
if (show_branch)
1357-
values = (char **) palloc((CONNECTBY_NCOLS + serial_column) * sizeof(char *));
1358-
else
1359-
values = (char **) palloc((CONNECTBY_NCOLS_NOBRANCH + serial_column) * sizeof(char *));
1360-
1361-
/* First time through, do a little setup */
1404+
/* First time through, do a little more setup */
13621405
if (level == 0)
13631406
{
13641407
/*
@@ -1373,45 +1416,6 @@ build_tuplestore_recursively(char *key_fld,
13731416
errmsg("invalid return type"),
13741417
errdetail("Return and SQL tuple descriptions are " \
13751418
"incompatible.")));
1376-
1377-
/* root value is the one we initially start with */
1378-
values[0] = start_with;
1379-
1380-
/* root value has no parent */
1381-
values[1] = NULL;
1382-
1383-
/* root level is 0 */
1384-
sprintf(current_level, "%d", level);
1385-
values[2] = current_level;
1386-
1387-
/* root branch is just starting root value */
1388-
if (show_branch)
1389-
values[3] = start_with;
1390-
1391-
/* root starts the serial with 1 */
1392-
if (show_serial)
1393-
{
1394-
sprintf(serial_str, "%d", (*serial)++);
1395-
if (show_branch)
1396-
values[4] = serial_str;
1397-
else
1398-
values[3] = serial_str;
1399-
}
1400-
1401-
/* construct the tuple */
1402-
tuple = BuildTupleFromCStrings(attinmeta, values);
1403-
1404-
/* switch to long lived context while storing the tuple */
1405-
oldcontext = MemoryContextSwitchTo(per_query_ctx);
1406-
1407-
/* now store it */
1408-
tuplestore_puttuple(tupstore, tuple);
1409-
1410-
/* now reset the context */
1411-
MemoryContextSwitchTo(oldcontext);
1412-
1413-
/* increment level */
1414-
level++;
14151419
}
14161420

14171421
for (i = 0; i < proc; i++)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy