@@ -1249,78 +1249,102 @@ DetachPeer(void)
1249
1249
}
1250
1250
1251
1251
/*
1252
- * Count progress of query execution like ratio of
1253
- * number of received to planned rows in persent.
1254
- * Changes of this function can lead to more plausible results .
1252
+ * Extract the number of actual rows and planned rows from
1253
+ * the plan for one node in text format. Returns their ratio,
1254
+ * or 1 if there are already more received than planned .
1255
1255
*/
1256
1256
static double
1257
- CountProgress (char * plan_text )
1257
+ CountNodeProgress (char * node_text )
1258
1258
{
1259
- char * plan ; /* Copy of plan_text */
1260
- char * node ; /* Part of plan with information about single node */
1261
1259
char * rows ; /* Pointer to rows */
1262
1260
char * actual_rows_str ; /* Actual rows in string format */
1263
1261
char * plan_rows_str ; /* Planned rows in string format */
1264
1262
int len ; /* Length of rows in string format */
1265
1263
double actual_rows ; /* Actual rows */
1266
1264
double plan_rows ; /* Planned rows */
1265
+
1266
+ rows = (char * ) (strstr (node_text , "\"Actual Rows\": " ) /* pointer to "Actual Rows" */
1267
+ + strlen ("\"Actual Rows\": " ) * sizeof (char )); /* shift by number of actual rows */
1268
+ len = strstr (rows , "\n" ) - rows ;
1269
+ if ((strstr (rows , "," ) - rows ) < len )
1270
+ len = strstr (rows , "," ) - rows ;
1271
+ actual_rows_str = palloc (sizeof (char ) * (len + 1 ));
1272
+ actual_rows_str [len ] = 0 ;
1273
+ strncpy (actual_rows_str , rows , len );
1274
+ actual_rows = strtod (actual_rows_str , NULL );
1275
+ pfree (actual_rows_str );
1276
+
1277
+ rows = strstr (node_text , "\"Plan Rows\": " );
1278
+ rows = (char * ) (rows + strlen ("\"Plan Rows\": " ) * sizeof (char ));
1279
+ len = strstr (rows , "," ) - rows ;
1280
+ plan_rows_str = palloc (sizeof (char ) * (len + 1 ));
1281
+ plan_rows_str [len ] = 0 ;
1282
+ strncpy (plan_rows_str , rows , len );
1283
+ plan_rows = strtod (plan_rows_str , NULL );
1284
+ pfree (plan_rows_str );
1285
+
1286
+ if (plan_rows > actual_rows )
1287
+ return actual_rows / plan_rows ;
1288
+ else
1289
+ return 1 ;
1290
+ }
1291
+
1292
+ /*
1293
+ * Count progress of query execution like ratio of
1294
+ * number of received to planned rows in persent.
1295
+ * Changes of this function can lead to more plausible results.
1296
+ */
1297
+ static double
1298
+ CountProgress (char * plan_text )
1299
+ {
1300
+ char * plan ; /* Copy of plan_text */
1301
+ char * node ; /* Part of plan with information about single node */
1302
+ char * rows ; /* Pointer to rows */
1267
1303
double progress = 0 ; /* Summary progress on nodes */
1268
1304
int node_amount = 0 ; /* Amount of plantree nodes using in counting progress */
1269
1305
1270
1306
plan = palloc (sizeof (char ) * (strlen (plan_text ) + 1 ));
1271
1307
strcpy (plan , plan_text );
1272
- node = strtok (plan , "[" ); /* Get information about upper node */
1308
+
1309
+ /*
1310
+ * plan_text contains information about upper node in format:
1311
+ * "Plan": {
1312
+ * and in different format for other nodes:
1313
+ * "Plans": [
1314
+ *
1315
+ * We will iterate over square brackets as over plan nodes.
1316
+ */
1317
+ node = strtok (plan , "[" ); /* Get information about first (but not upper) node */
1318
+
1319
+ /* Iterating over nodes */
1273
1320
while (node != NULL )
1274
1321
{
1275
- if (strstr (node , "Seq Scan" ) == NULL )
1322
+ /* Result and Modify Table nodes must be skipped */
1323
+ if ((strstr (node , "Result" ) == NULL ) && (strstr (node , "ModifyTable" ) == NULL ))
1276
1324
{
1277
- if (strstr (node , "ModifyTable" ) == NULL )
1325
+ /* Filter node */
1326
+ if ((rows = strstr (node , "Rows Removed by Filter" )) != NULL )
1278
1327
{
1279
- if (strstr (node , "Result" ) == NULL )
1280
- {
1281
- if ((rows = strstr (node , "Rows Removed by Filter" )) != NULL )
1282
- {
1283
- node_amount ++ ;
1284
- rows = (char * ) (rows + strlen ("Rows Removed by Filter\": " ) * sizeof (char ));
1285
-
1286
- /*
1287
- * Filter node have 2 conditions:
1288
- * 1) Was not filtered (current progress = 0)
1289
- * 2) Was filtered (current progress = 1)
1290
- */
1291
- if (rows [0 ] != '0' )
1292
- progress += 1 ;
1293
- }
1294
- else if ((rows = strstr (node , "\"Actual Rows\": " )) != NULL )
1295
- {
1296
- node_amount ++ ;
1297
- rows = (char * ) (rows + strlen ("\"Actual Rows\": " ) * sizeof (char ));
1298
- len = strstr (rows , "\n" ) - rows ;
1299
- if ((strstr (rows , "," ) - rows ) < len )
1300
- len = strstr (rows , "," ) - rows ;
1301
- actual_rows_str = palloc (sizeof (char ) * (len + 1 ));
1302
- actual_rows_str [len ] = 0 ;
1303
- strncpy (actual_rows_str , rows , len );
1304
- actual_rows = strtod (actual_rows_str , NULL );
1305
- pfree (actual_rows_str );
1306
-
1307
- rows = strstr (node , "\"Plan Rows\": " );
1308
- rows = (char * ) (rows + strlen ("\"Plan Rows\": " ) * sizeof (char ));
1309
- len = strstr (rows , "," ) - rows ;
1310
- plan_rows_str = palloc (sizeof (char ) * (len + 1 ));
1311
- plan_rows_str [len ] = 0 ;
1312
- strncpy (plan_rows_str , rows , len );
1313
- plan_rows = strtod (plan_rows_str , NULL );
1314
- pfree (plan_rows_str );
1315
-
1316
- if (plan_rows > actual_rows )
1317
- progress += actual_rows / plan_rows ;
1318
- else
1319
- progress += 1 ;
1320
- }
1321
- }
1328
+ node_amount ++ ;
1329
+ rows = (char * ) (rows + strlen ("Rows Removed by Filter\": " ) * sizeof (char ));
1330
+
1331
+ /*
1332
+ * Filter node have 2 conditions:
1333
+ * 1) Was not filtered (current progress = 0)
1334
+ * 2) Was filtered (current progress = 1)
1335
+ */
1336
+ if (rows [0 ] != '0' )
1337
+ progress += 1 ;
1338
+ }
1339
+ /* Not Filter node */
1340
+ else if (strstr (node , "\"Actual Rows\": " ) != NULL )
1341
+ {
1342
+ node_amount ++ ;
1343
+ progress += CountNodeProgress (node );
1322
1344
}
1323
1345
}
1346
+
1347
+ /* Get next node */
1324
1348
node = strtok (NULL , "[" );
1325
1349
}
1326
1350
0 commit comments