@@ -325,14 +325,15 @@ func (h *Hub) LoadConnectionConfig() (bool, error) {
325325}
326326
327327// GetRelSize is a method called from the planner to estimate the resulting relation size for a scan.
328- // It will help the planner in deciding between different types of plans,
329- // according to their costs.
330- // Args:
331- // columns (list): The list of columns that must be returned.
332- // quals (list): A list of Qual instances describing the filters
333- // applied to this scan.
334- // Returns:
335- // A struct of the form (expected_number_of_rows, avg_row_width (in bytes))
328+ //
329+ // It will help the planner in deciding between different types of plans,
330+ // according to their costs.
331+ // Args:
332+ // columns (list): The list of columns that must be returned.
333+ // quals (list): A list of Qual instances describing the filters
334+ // applied to this scan.
335+ // Returns:
336+ // A struct of the form (expected_number_of_rows, avg_row_width (in bytes))
336337func (h * Hub ) GetRelSize (columns []string , quals []* proto.Qual , opts types.Options ) (types.RelSize , error ) {
337338 result := types.RelSize {
338339 // Default to 1M rows, because these tables are typically expensive
@@ -345,43 +346,44 @@ func (h *Hub) GetRelSize(columns []string, quals []*proto.Qual, opts types.Optio
345346}
346347
347348// GetPathKeys Is a method called from the planner to add additional Path to the planner.
348- // By default, the planner generates an (unparameterized) path, which
349- // can be reasoned about like a SequentialScan, optionally filtered.
350- // This method allows the implementor to declare other Paths,
351- // corresponding to faster access methods for specific attributes.
352- // Such a parameterized path can be reasoned about like an IndexScan.
353- // For example, with the following query::
354- // select * from foreign_table inner join local_table using(id);
355- // where foreign_table is a foreign table containing 100000 rows, and
356- // local_table is a regular table containing 100 rows.
357- // The previous query would probably be transformed to a plan similar to
358- // this one::
359- // ┌────────────────────────────────────────────────────────────────────────────────────┐
360- // │ QUERY PLAN │
361- // ├────────────────────────────────────────────────────────────────────────────────────┤
362- // │ Hash Join (cost=57.67..4021812.67 rows=615000 width=68) │
363- // │ Hash Cond: (foreign_table.id = local_table.id) │
364- // │ -> Foreign Scan on foreign_table (cost=20.00..4000000.00 rows=100000 width=40) │
365- // │ -> Hash (cost=22.30..22.30 rows=1230 width=36) │
366- // │ -> Seq Scan on local_table (cost=0.00..22.30 rows=1230 width=36) │
367- // └────────────────────────────────────────────────────────────────────────────────────┘
368- // But with a parameterized path declared on the id key, with the knowledge that this key
369- // is unique on the foreign side, the following plan might get chosen::
370- // ┌───────────────────────────────────────────────────────────────────────┐
371- // │ QUERY PLAN │
372- // ├───────────────────────────────────────────────────────────────────────┤
373- // │ Nested Loop (cost=20.00..49234.60 rows=615000 width=68) │
374- // │ -> Seq Scan on local_table (cost=0.00..22.30 rows=1230 width=36) │
375- // │ -> Foreign Scan on remote_table (cost=20.00..40.00 rows=1 width=40)│
376- // │ Filter: (id = local_table.id) │
377- // └───────────────────────────────────────────────────────────────────────┘
378- // Returns:
379- // A list of tuples of the form: (key_columns, expected_rows),
380- // where key_columns is a tuple containing the columns on which
381- // the path can be used, and expected_rows is the number of rows
382- // this path might return for a simple lookup.
383- // For example, the return value corresponding to the previous scenario would be::
384- // [(('id',), 1)]
349+ //
350+ // By default, the planner generates an (unparameterized) path, which
351+ // can be reasoned about like a SequentialScan, optionally filtered.
352+ // This method allows the implementor to declare other Paths,
353+ // corresponding to faster access methods for specific attributes.
354+ // Such a parameterized path can be reasoned about like an IndexScan.
355+ // For example, with the following query::
356+ // select * from foreign_table inner join local_table using(id);
357+ // where foreign_table is a foreign table containing 100000 rows, and
358+ // local_table is a regular table containing 100 rows.
359+ // The previous query would probably be transformed to a plan similar to
360+ // this one::
361+ // ┌────────────────────────────────────────────────────────────────────────────────────┐
362+ // │ QUERY PLAN │
363+ // ├────────────────────────────────────────────────────────────────────────────────────┤
364+ // │ Hash Join (cost=57.67..4021812.67 rows=615000 width=68) │
365+ // │ Hash Cond: (foreign_table.id = local_table.id) │
366+ // │ -> Foreign Scan on foreign_table (cost=20.00..4000000.00 rows=100000 width=40) │
367+ // │ -> Hash (cost=22.30..22.30 rows=1230 width=36) │
368+ // │ -> Seq Scan on local_table (cost=0.00..22.30 rows=1230 width=36) │
369+ // └────────────────────────────────────────────────────────────────────────────────────┘
370+ // But with a parameterized path declared on the id key, with the knowledge that this key
371+ // is unique on the foreign side, the following plan might get chosen::
372+ // ┌───────────────────────────────────────────────────────────────────────┐
373+ // │ QUERY PLAN │
374+ // ├───────────────────────────────────────────────────────────────────────┤
375+ // │ Nested Loop (cost=20.00..49234.60 rows=615000 width=68) │
376+ // │ -> Seq Scan on local_table (cost=0.00..22.30 rows=1230 width=36) │
377+ // │ -> Foreign Scan on remote_table (cost=20.00..40.00 rows=1 width=40)│
378+ // │ Filter: (id = local_table.id) │
379+ // └───────────────────────────────────────────────────────────────────────┘
380+ // Returns:
381+ // A list of tuples of the form: (key_columns, expected_rows),
382+ // where key_columns is a tuple containing the columns on which
383+ // the path can be used, and expected_rows is the number of rows
384+ // this path might return for a simple lookup.
385+ // For example, the return value corresponding to the previous scenario would be::
386+ // [(('id',), 1)]
385387func (h * Hub ) GetPathKeys (opts types.Options ) ([]types.PathKey , error ) {
386388
387389 connectionName := opts ["connection" ]
@@ -440,8 +442,9 @@ func (h *Hub) GetPathKeys(opts types.Options) ([]types.PathKey, error) {
440442}
441443
442444// Explain :: hook called on explain.
443- // Returns:
444- // An iterable of strings to display in the EXPLAIN output.
445+ //
446+ // Returns:
447+ // An iterable of strings to display in the EXPLAIN output.
445448func (h * Hub ) Explain (columns []string , quals []* proto.Qual , sortKeys []string , verbose bool , opts types.Options ) ([]string , error ) {
446449 return make ([]string , 0 ), nil
447450}
@@ -715,12 +718,13 @@ func (h *Hub) getConnectionPlugin(connectionName string) (*steampipeconfig.Conne
715718 // get the plugin FQN
716719 connectionConfig , ok := steampipeconfig .GlobalConfig .Connections [connectionName ]
717720 if ! ok {
721+ log .Printf ("[WARN] no connection config loaded for connection '%s'" , connectionName )
718722 return nil , fmt .Errorf ("no connection config loaded for connection '%s'" , connectionName )
719723 }
720724 pluginFQN := connectionConfig .Plugin
721725
722726 // ask connection map to get or create this connection
723- c , err := h .connections .createConnectionPlugin (pluginFQN , connectionName )
727+ c , err := h .connections .getOrCreate (pluginFQN , connectionName )
724728 if err != nil {
725729 return nil , err
726730 }
0 commit comments