@@ -16,6 +16,7 @@ use once_cell::sync::Lazy;
16
16
use serde:: Serialize ;
17
17
use uncased:: UncasedStr ;
18
18
19
+ use mz_build_info:: BuildInfo ;
19
20
use mz_ore:: cast;
20
21
use mz_sql:: ast:: { Ident , SetVariableValue , Value as AstValue } ;
21
22
use mz_sql:: DEFAULT_SCHEMA ;
@@ -125,6 +126,8 @@ const INTERVAL_STYLE: ServerVar<str> = ServerVar {
125
126
internal : false ,
126
127
} ;
127
128
129
+ const MZ_VERSION_NAME : & UncasedStr = UncasedStr :: new ( "mz_version" ) ;
130
+
128
131
const QGM_OPTIMIZATIONS : ServerVar < bool > = ServerVar {
129
132
name : UncasedStr :: new ( "qgm_optimizations_experimental" ) ,
130
133
value : & false ,
@@ -399,6 +402,7 @@ static EMIT_TRACE_ID_NOTICE: ServerVar<bool> = ServerVar {
399
402
#[ derive( Debug ) ]
400
403
pub struct SessionVars {
401
404
application_name : SessionVar < str > ,
405
+ build_info : & ' static BuildInfo ,
402
406
client_encoding : ServerVar < str > ,
403
407
client_min_messages : SessionVar < ClientSeverity > ,
404
408
cluster : SessionVar < str > ,
@@ -424,10 +428,12 @@ pub struct SessionVars {
424
428
emit_trace_id_notice : SessionVar < bool > ,
425
429
}
426
430
427
- impl Default for SessionVars {
428
- fn default ( ) -> SessionVars {
431
+ impl SessionVars {
432
+ /// Creates a new [`SessionVars`].
433
+ pub fn new ( build_info : & ' static BuildInfo ) -> SessionVars {
429
434
SessionVars {
430
435
application_name : SessionVar :: new ( & APPLICATION_NAME ) ,
436
+ build_info,
431
437
client_encoding : CLIENT_ENCODING ,
432
438
client_min_messages : SessionVar :: new ( & CLIENT_MIN_MESSAGES ) ,
433
439
cluster : SessionVar :: new ( & CLUSTER ) ,
@@ -455,24 +461,20 @@ impl Default for SessionVars {
455
461
emit_trace_id_notice : SessionVar :: new ( & EMIT_TRACE_ID_NOTICE ) ,
456
462
}
457
463
}
458
- }
459
464
460
- impl SessionVars {
461
465
/// Returns a new SessionVars with the cluster variable set to `cluster`.
462
- pub fn for_cluster ( cluster_name : & str ) -> Self {
463
- let mut cluster = SessionVar :: new ( & CLUSTER ) ;
464
- cluster. session_value = Some ( cluster_name. into ( ) ) ;
465
- Self {
466
- cluster,
467
- ..Default :: default ( )
468
- }
466
+ pub fn for_cluster ( build_info : & ' static BuildInfo , cluster_name : & str ) -> Self {
467
+ let mut vars = SessionVars :: new ( build_info) ;
468
+ vars. cluster . session_value = Some ( cluster_name. into ( ) ) ;
469
+ vars
469
470
}
470
471
471
472
/// Returns an iterator over the configuration parameters and their current
472
473
/// values for this session.
473
474
pub fn iter ( & self ) -> impl Iterator < Item = & dyn Var > {
474
- let vars: [ & dyn Var ; 24 ] = [
475
+ let vars: [ & dyn Var ; 25 ] = [
475
476
& self . application_name ,
477
+ self . build_info ,
476
478
& self . client_encoding ,
477
479
& self . client_min_messages ,
478
480
& self . cluster ,
@@ -504,7 +506,7 @@ impl SessionVars {
504
506
/// values for this session) that are expected to be sent to the client when
505
507
/// a new connection is established or when their value changes.
506
508
pub fn notify_set ( & self ) -> impl Iterator < Item = & dyn Var > {
507
- let vars: [ & dyn Var ; 8 ] = [
509
+ let vars: [ & dyn Var ; 9 ] = [
508
510
& self . application_name ,
509
511
& self . client_encoding ,
510
512
& self . date_style ,
@@ -513,6 +515,13 @@ impl SessionVars {
513
515
& self . standard_conforming_strings ,
514
516
& self . timezone ,
515
517
& self . interval_style ,
518
+ // Including `mz_version` in the notify set is a Materialize
519
+ // extension. Doing so allows applications to detect whether they
520
+ // are talking to Materialize or PostgreSQL without an additional
521
+ // network roundtrip. This is known to be safe because CockroachDB
522
+ // has an analogous extension [0].
523
+ // [0]: https://github.com/cockroachdb/cockroach/blob/369c4057a/pkg/sql/pgwire/conn.go#L1840
524
+ self . build_info ,
516
525
] ;
517
526
vars. into_iter ( )
518
527
}
@@ -550,6 +559,8 @@ impl SessionVars {
550
559
Ok ( & self . integer_datetimes )
551
560
} else if name == INTERVAL_STYLE . name {
552
561
Ok ( & self . interval_style )
562
+ } else if name == MZ_VERSION_NAME {
563
+ Ok ( self . build_info )
553
564
} else if name == QGM_OPTIMIZATIONS . name {
554
565
Ok ( & self . qgm_optimizations )
555
566
} else if name == SEARCH_PATH . name {
@@ -789,6 +800,7 @@ impl SessionVars {
789
800
// call to `end_transaction` below.
790
801
let SessionVars {
791
802
application_name,
803
+ build_info : _,
792
804
client_encoding : _,
793
805
client_min_messages,
794
806
cluster,
@@ -836,6 +848,11 @@ impl SessionVars {
836
848
self . application_name . value ( )
837
849
}
838
850
851
+ /// Returns the build info.
852
+ pub fn build_info ( & self ) -> & ' static BuildInfo {
853
+ self . build_info
854
+ }
855
+
839
856
/// Returns the value of the `client_encoding` configuration parameter.
840
857
pub fn client_encoding ( & self ) -> & ' static str {
841
858
self . client_encoding . value
@@ -881,6 +898,11 @@ impl SessionVars {
881
898
self . interval_style . value
882
899
}
883
900
901
+ /// Returns the value of the `mz_version` configuration parameter.
902
+ pub fn mz_version ( & self ) -> String {
903
+ self . build_info . value ( )
904
+ }
905
+
884
906
/// Returns the value of the `qgm_optimizations` configuration parameter.
885
907
pub fn qgm_optimizations ( & self ) -> bool {
886
908
* self . qgm_optimizations . value ( )
@@ -1589,6 +1611,28 @@ where
1589
1611
}
1590
1612
}
1591
1613
1614
+ impl Var for BuildInfo {
1615
+ fn name ( & self ) -> & ' static str {
1616
+ "mz_version"
1617
+ }
1618
+
1619
+ fn value ( & self ) -> String {
1620
+ self . human_version ( )
1621
+ }
1622
+
1623
+ fn description ( & self ) -> & ' static str {
1624
+ "Shows the Materialize server version (Materialize)."
1625
+ }
1626
+
1627
+ fn type_name ( & self ) -> & ' static str {
1628
+ str:: TYPE_NAME
1629
+ }
1630
+
1631
+ fn visible ( & self , _: & User ) -> bool {
1632
+ true
1633
+ }
1634
+ }
1635
+
1592
1636
/// A value that can be stored in a session or server variable.
1593
1637
pub trait Value : ToOwned + Send + Sync {
1594
1638
/// The name of the value type.
0 commit comments