@@ -1295,70 +1295,113 @@ build_tuplestore_recursively(char *key_fld,
12951295int ret ;
12961296int proc ;
12971297int 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
12991309if (max_depth > 0 && level > max_depth )
13001310return 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 */
13031320if (!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 " ,
13061323key_fld ,
13071324parent_key_fld ,
13081325relname ,
13091326parent_key_fld ,
13101327start_with ,
1311- key_fld );
1328+ key_fld , key_fld , parent_key_fld );
13121329serial_column = 0 ;
13131330}
13141331else
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 NULLAND %s <> %s ORDER BY %s" ,
13171334key_fld ,
13181335parent_key_fld ,
13191336relname ,
13201337parent_key_fld ,
13211338start_with ,
1322- key_fld ,
1339+ key_fld ,key_fld , parent_key_fld ,
13231340orderby_fld );
13241341serial_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 */
13281393ret = SPI_exec (sql -> data ,0 );
13291394proc = SPI_processed ;
13301395
13311396/* Check for qualifying tuples */
13321397if ((ret == SPI_OK_SELECT )&& (proc > 0 ))
13331398{
1334- HeapTuple tuple ;
13351399HeapTuple spi_tuple ;
13361400SPITupleTable * tuptable = SPI_tuptable ;
13371401TupleDesc spi_tupdesc = tuptable -> tupdesc ;
13381402int 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 */
13621405if (level == 0 )
13631406{
13641407/*
@@ -1373,45 +1416,6 @@ build_tuplestore_recursively(char *key_fld,
13731416errmsg ("invalid return type" ),
13741417errdetail ("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
14171421for (i = 0 ;i < proc ;i ++ )