Index: contrib/tablefunc/tablefunc.c =================================================================== RCS file: /opt/src/cvs/pgsql-server/contrib/tablefunc/tablefunc.c,v retrieving revision 1.24 diff -c -r1.24 tablefunc.c *** contrib/tablefunc/tablefunc.c 13 Sep 2003 21:44:50 -0000 1.24 --- contrib/tablefunc/tablefunc.c 1 Oct 2003 22:47:11 -0000 *************** *** 1295,1329 **** 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; --- 1295,1394 ---- int ret; int proc; int serial_column; + 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; + HeapTuple tuple; if (max_depth > 0 && level > max_depth) return tupstore; + /* start a new branch */ + branchstr = makeStringInfo(); + + /* need these to check for recursion */ + 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 + values = (char **) palloc((CONNECTBY_NCOLS_NOBRANCH + serial_column) * sizeof(char *)); + + /* First time through, do a little setup */ + if (level == 0) + { + /* root value is the one we initially start with */ + values[0] = start_with; + + /* root value has no parent */ + values[1] = NULL; + + /* root level is 0 */ + sprintf(current_level, "%d", level); + values[2] = current_level; + + /* root branch is just starting root value */ + if (show_branch) + values[3] = start_with; + + /* root starts the serial with 1 */ + if (show_serial) + { + sprintf(serial_str, "%d", (*serial)++); + if (show_branch) + values[4] = serial_str; + else + values[3] = serial_str; + } + + /* construct the tuple */ + tuple = BuildTupleFromCStrings(attinmeta, values); + + /* switch to long lived context while storing the tuple */ + oldcontext = MemoryContextSwitchTo(per_query_ctx); + + /* now store it */ + tuplestore_puttuple(tupstore, tuple); + + /* now reset the context */ + MemoryContextSwitchTo(oldcontext); + + /* increment level */ + level++; + } + /* Retrieve the desired rows */ ret = SPI_exec(sql->data, 0); proc = SPI_processed; *************** *** 1331,1364 **** /* 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; - 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; - - /* start a new branch */ - branchstr = makeStringInfo(); - - /* need these to check for recursion */ - chk_branchstr = makeStringInfo(); - chk_current_key = makeStringInfo(); ! if (show_branch) ! values = (char **) palloc((CONNECTBY_NCOLS + serial_column) * sizeof(char *)); ! else ! values = (char **) palloc((CONNECTBY_NCOLS_NOBRANCH + serial_column) * sizeof(char *)); ! ! /* First time through, do a little setup */ if (level == 0) { /* --- 1396,1407 ---- /* 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) { /* *************** *** 1373,1417 **** 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; - - /* root value has no parent */ - values[1] = NULL; - - /* root level is 0 */ - sprintf(current_level, "%d", level); - values[2] = current_level; - - /* root branch is just starting root value */ - if (show_branch) - values[3] = start_with; - - /* root starts the serial with 1 */ - if (show_serial) - { - sprintf(serial_str, "%d", (*serial)++); - if (show_branch) - values[4] = serial_str; - else - values[3] = serial_str; - } - - /* construct the tuple */ - tuple = BuildTupleFromCStrings(attinmeta, values); - - /* switch to long lived context while storing the tuple */ - oldcontext = MemoryContextSwitchTo(per_query_ctx); - - /* now store it */ - tuplestore_puttuple(tupstore, tuple); - - /* now reset the context */ - MemoryContextSwitchTo(oldcontext); - - /* increment level */ - level++; } for (i = 0; i < proc; i++) --- 1416,1421 ---- Index: contrib/tablefunc/expected/tablefunc.out =================================================================== RCS file: /opt/src/cvs/pgsql-server/contrib/tablefunc/expected/tablefunc.out,v retrieving revision 1.9 diff -c -r1.9 tablefunc.out *** contrib/tablefunc/expected/tablefunc.out 13 Sep 2003 21:44:50 -0000 1.9 --- contrib/tablefunc/expected/tablefunc.out 1 Oct 2003 22:34:32 -0000 *************** *** 127,133 **** -- 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" 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 --- 127,133 ---- -- 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" 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