@@ -8448,15 +8448,11 @@ YbUseMinimalCatalogCachesPreload()
84488448 return false;
84498449}
84508450
8451- /* Sort replica indices lexicographically while keeping parallel arrays aligned. */
8451+ /* Comparison function for sorting strings in a List */
84528452static int
8453- replica_index_cmp (const void * a , const void * b , void * arg )
8453+ string_list_compare (const ListCell * a , const ListCell * b )
84548454{
8455- const char * * replicas = (const char * * ) arg ;
8456- int ia = * (const int * ) a ;
8457- int ib = * (const int * ) b ;
8458-
8459- return strcmp (replicas [ia ], replicas [ib ]);
8455+ return strcmp ((char * ) lfirst (a ), (char * ) lfirst (b ));
84608456}
84618457
84628458/*
@@ -8556,97 +8552,98 @@ yb_get_tablet_metadata(PG_FUNCTION_ARGS)
85568552 nulls [6 ] = true;
85578553 }
85588554
8559- /* Convert replicas array to PostgreSQL text array and JSONB attributes */
8555+ /* Convert replicas to PostgreSQL text array and build JSONB attributes */
85608556 if (tablet -> replicas_count > 0 )
85618557 {
85628558 size_t nreplicas = tablet -> replicas_count ;
8563- int * sort_idxs ;
8564- Datum * text_elems ;
8565- JsonbParseState * jb_state = NULL ;
8566- JsonbValue jb_result ;
8567- JsonbValue jb_key ;
8568- JsonbValue jb_val ;
85698559
85708560 Assert (tablet -> replicas != NULL );
85718561
85728562 /* The last replica is the leader. */
85738563 values [7 ] = CStringGetTextDatum (tablet -> replicas [nreplicas - 1 ]);
85748564
85758565 /*
8576- * Build a sort index so replicas stay in lexicographic order.
8566+ * Build JSONB attributes before sorting replicas, because the
8567+ * parallel size arrays must stay aligned with the replica order.
8568+ * JSONB does not preserve key order so sorting is unnecessary.
85778569 */
8578- sort_idxs = palloc (nreplicas * sizeof (int ));
8579- for (size_t idx = 0 ; idx < nreplicas ; idx ++ )
8580- sort_idxs [idx ] = (int ) idx ;
8581-
8582- qsort_arg (sort_idxs , nreplicas , sizeof (int ),
8583- replica_index_cmp , tablet -> replicas );
8584-
8585- text_elems = palloc (nreplicas * sizeof (Datum ));
8586-
8587- /* Build JSONB: {"replicas": {"addr": {"active_sst_sizes": N, "wal_sizes": N}, ...}} */
8588- pushJsonbValue (& jb_state , WJB_BEGIN_OBJECT , NULL );
8589-
8590- jb_key .type = jbvString ;
8591- jb_key .val .string .val = "replicas" ;
8592- jb_key .val .string .len = 8 ;
8593- pushJsonbValue (& jb_state , WJB_KEY , & jb_key );
8594-
8595- pushJsonbValue (& jb_state , WJB_BEGIN_OBJECT , NULL );
8596-
8597- for (size_t idx = 0 ; idx < nreplicas ; idx ++ )
85988570 {
8599- int si = sort_idxs [idx ];
8600- int64 sst_size ;
8601- int64 wal_size ;
8602-
8603- text_elems [idx ] = CStringGetTextDatum (tablet -> replicas [si ]);
8571+ JsonbParseState * jb_state = NULL ;
8572+ JsonbValue jb_result ;
8573+ JsonbValue jb_key ;
8574+ JsonbValue jb_val ;
86048575
8605- sst_size = tablet -> replica_sst_sizes
8606- ? tablet -> replica_sst_sizes [si ] : 0 ;
8607- wal_size = tablet -> replica_wal_sizes
8608- ? tablet -> replica_wal_sizes [si ] : 0 ;
8576+ /* {"replicas": {"addr": {"active_sst_sizes": N, "wal_sizes": N}, ...}} */
8577+ pushJsonbValue (& jb_state , WJB_BEGIN_OBJECT , NULL );
86098578
8610- /* Replica address as key */
86118579 jb_key .type = jbvString ;
8612- jb_key .val .string .val = ( char * ) tablet -> replicas [ si ] ;
8613- jb_key .val .string .len = strlen ( tablet -> replicas [ si ]) ;
8580+ jb_key .val .string .val = " replicas" ;
8581+ jb_key .val .string .len = 8 ;
86148582 pushJsonbValue (& jb_state , WJB_KEY , & jb_key );
86158583
8616- /* Per-replica object */
86178584 pushJsonbValue (& jb_state , WJB_BEGIN_OBJECT , NULL );
86188585
8619- jb_key .type = jbvString ;
8620- jb_key .val .string .val = "active_sst_sizes" ;
8621- jb_key .val .string .len = 16 ;
8622- pushJsonbValue (& jb_state , WJB_KEY , & jb_key );
8623- jb_val .type = jbvNumeric ;
8624- jb_val .val .numeric = DatumGetNumeric (
8625- DirectFunctionCall1 (int8_numeric , Int64GetDatum (sst_size )));
8626- pushJsonbValue (& jb_state , WJB_VALUE , & jb_val );
8586+ for (size_t idx = 0 ; idx < nreplicas ; idx ++ )
8587+ {
8588+ int64 sst_size ;
8589+ int64 wal_size ;
8590+
8591+ sst_size = tablet -> replica_sst_sizes
8592+ ? tablet -> replica_sst_sizes [idx ] : 0 ;
8593+ wal_size = tablet -> replica_wal_sizes
8594+ ? tablet -> replica_wal_sizes [idx ] : 0 ;
8595+
8596+ /* Replica address as key */
8597+ jb_key .type = jbvString ;
8598+ jb_key .val .string .val = (char * ) tablet -> replicas [idx ];
8599+ jb_key .val .string .len = strlen (tablet -> replicas [idx ]);
8600+ pushJsonbValue (& jb_state , WJB_KEY , & jb_key );
8601+
8602+ /* Per-replica object */
8603+ pushJsonbValue (& jb_state , WJB_BEGIN_OBJECT , NULL );
8604+
8605+ jb_key .type = jbvString ;
8606+ jb_key .val .string .val = "active_sst_sizes" ;
8607+ jb_key .val .string .len = 16 ;
8608+ pushJsonbValue (& jb_state , WJB_KEY , & jb_key );
8609+ jb_val .type = jbvNumeric ;
8610+ jb_val .val .numeric = DatumGetNumeric (
8611+ DirectFunctionCall1 (int8_numeric , Int64GetDatum (sst_size )));
8612+ pushJsonbValue (& jb_state , WJB_VALUE , & jb_val );
8613+
8614+ jb_key .type = jbvString ;
8615+ jb_key .val .string .val = "wal_sizes" ;
8616+ jb_key .val .string .len = 9 ;
8617+ pushJsonbValue (& jb_state , WJB_KEY , & jb_key );
8618+ jb_val .type = jbvNumeric ;
8619+ jb_val .val .numeric = DatumGetNumeric (
8620+ DirectFunctionCall1 (int8_numeric , Int64GetDatum (wal_size )));
8621+ pushJsonbValue (& jb_state , WJB_VALUE , & jb_val );
8622+
8623+ pushJsonbValue (& jb_state , WJB_END_OBJECT , NULL );
8624+ }
86278625
8628- jb_key .type = jbvString ;
8629- jb_key .val .string .val = "wal_sizes" ;
8630- jb_key .val .string .len = 9 ;
8631- pushJsonbValue (& jb_state , WJB_KEY , & jb_key );
8632- jb_val .type = jbvNumeric ;
8633- jb_val .val .numeric = DatumGetNumeric (
8634- DirectFunctionCall1 (int8_numeric , Int64GetDatum (wal_size )));
8635- pushJsonbValue (& jb_state , WJB_VALUE , & jb_val );
8626+ pushJsonbValue (& jb_state , WJB_END_OBJECT , NULL ); /* end replicas */
8627+ jb_result = * pushJsonbValue (& jb_state , WJB_END_OBJECT , NULL ); /* end outer */
86368628
8637- pushJsonbValue ( & jb_state , WJB_END_OBJECT , NULL );
8629+ values [ 9 ] = JsonbPGetDatum ( JsonbValueToJsonb ( & jb_result ) );
86388630 }
86398631
8640- pushJsonbValue (& jb_state , WJB_END_OBJECT , NULL ); /* end replicas */
8641- jb_result = * pushJsonbValue (& jb_state , WJB_END_OBJECT , NULL ); /* end outer */
8632+ /* Convert char ** to List * */
8633+ {
8634+ List * replicas_list = NIL ;
86428635
8643- values [8 ] = PointerGetDatum (
8644- construct_array (text_elems , (int ) nreplicas ,
8645- TEXTOID , -1 , false, TYPALIGN_INT ));
8646- values [9 ] = JsonbPGetDatum (JsonbValueToJsonb (& jb_result ));
8636+ for (size_t idx = 0 ; idx < nreplicas ; idx ++ )
8637+ replicas_list = lappend (replicas_list ,
8638+ (char * ) tablet -> replicas [idx ]);
86478639
8648- pfree (sort_idxs );
8649- pfree (text_elems );
8640+ /*
8641+ * Sort the list lexicographically for consistency, so that
8642+ * all rows with same replicas have same entries.
8643+ */
8644+ list_sort (replicas_list , string_list_compare );
8645+ values [8 ] = PointerGetDatum (strlist_to_textarray (replicas_list ));
8646+ }
86508647 }
86518648 else
86528649 {
0 commit comments