@@ -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