@@ -757,6 +757,87 @@ add_replication_telemetry(JsonbParseState *state)
757
757
#define REQ_RELS_CONTINUOUS_AGGS "continuous_aggregates"
758
758
#define REQ_FUNCTIONS_USED "functions_used"
759
759
#define REQ_REPLICATION "replication"
760
+ #define REQ_ACCESS_METHODS "access_methods"
761
+
762
+ /*
763
+ * Add the result of a query as a sub-object to the JSONB.
764
+ *
765
+ * Each row from the query generates a separate object keyed by one of the
766
+ * columns. Each row will be represented as an object and stored under the
767
+ * "key" column. For example, with this query:
768
+ *
769
+ * select amname as name,
770
+ * sum(relpages) as pages,
771
+ * count(*) as instances
772
+ * from pg_class join pg_am on relam = pg_am.oid
773
+ * group by pg_am.oid;
774
+ *
775
+ * might generate the object
776
+ *
777
+ * {
778
+ * "brin" : {
779
+ * "instances" : 44,
780
+ * "pages" : 432
781
+ * },
782
+ * "btree" : {
783
+ * "instances" : 99,
784
+ * "pages" : 1234
785
+ * }
786
+ * }
787
+ */
788
+ static void
789
+ add_query_result_dict (JsonbParseState * state , const char * query )
790
+ {
791
+ MemoryContext orig_context = CurrentMemoryContext ;
792
+
793
+ int res ;
794
+ if (SPI_connect () != SPI_OK_CONNECT )
795
+ elog (ERROR , "could not connect to SPI" );
796
+
797
+ /* Lock down search_path */
798
+ res = SPI_execute ("SET LOCAL search_path TO pg_catalog, pg_temp" , false, 0 );
799
+ Ensure (res >= 0 , "could not set search path" );
800
+
801
+ res = SPI_execute (query , true, 0 );
802
+ Ensure (res >= 0 , "could not execute query" );
803
+
804
+ MemoryContext spi_context = MemoryContextSwitchTo (orig_context );
805
+
806
+ (void ) pushJsonbValue (& state , WJB_BEGIN_OBJECT , NULL );
807
+ for (uint64 r = 0 ; r < SPI_processed ; r ++ )
808
+ {
809
+ char * key_string = SPI_getvalue (SPI_tuptable -> vals [r ], SPI_tuptable -> tupdesc , 1 );
810
+ JsonbValue key = {
811
+ .type = jbvString ,
812
+ .val .string .val = pstrdup (key_string ),
813
+ .val .string .len = strlen (key_string ),
814
+ };
815
+
816
+ (void ) pushJsonbValue (& state , WJB_KEY , & key );
817
+
818
+ (void ) pushJsonbValue (& state , WJB_BEGIN_OBJECT , NULL );
819
+ for (int c = 1 ; c < SPI_tuptable -> tupdesc -> natts ; ++ c )
820
+ {
821
+ bool isnull ;
822
+ Datum val_datum =
823
+ SPI_getbinval (SPI_tuptable -> vals [r ], SPI_tuptable -> tupdesc , c + 1 , & isnull );
824
+ if (!isnull )
825
+ {
826
+ char * key_string = SPI_fname (SPI_tuptable -> tupdesc , c + 1 );
827
+ JsonbValue value ;
828
+ ts_jsonb_set_value_by_type (& value ,
829
+ SPI_gettypeid (SPI_tuptable -> tupdesc , c + 1 ),
830
+ val_datum );
831
+ ts_jsonb_add_value (state , key_string , & value );
832
+ }
833
+ }
834
+ pushJsonbValue (& state , WJB_END_OBJECT , NULL );
835
+ }
836
+ MemoryContextSwitchTo (spi_context );
837
+ res = SPI_finish ();
838
+ Assert (res == SPI_OK_FINISH );
839
+ (void ) pushJsonbValue (& state , WJB_END_OBJECT , NULL );
840
+ }
760
841
761
842
static Jsonb *
762
843
build_telemetry_report ()
@@ -937,6 +1018,15 @@ build_telemetry_report()
937
1018
add_replication_telemetry (parse_state );
938
1019
pushJsonbValue (& parse_state , WJB_END_OBJECT , NULL );
939
1020
1021
+ key .type = jbvString ;
1022
+ key .val .string .val = REQ_ACCESS_METHODS ;
1023
+ key .val .string .len = strlen (REQ_ACCESS_METHODS );
1024
+ (void ) pushJsonbValue (& parse_state , WJB_KEY , & key );
1025
+ add_query_result_dict (parse_state ,
1026
+ "SELECT amname AS name, sum(relpages) AS pages, count(*) AS "
1027
+ "instances FROM pg_class JOIN pg_am ON relam = pg_am.oid "
1028
+ "GROUP BY amname" );
1029
+
940
1030
/* end of telemetry object */
941
1031
result = pushJsonbValue (& parse_state , WJB_END_OBJECT , NULL );
942
1032
0 commit comments