feat(tools/postgres)!: Add additional filter params for existing postgres tools (#2033)

## Description

Add additional filter parameters for existing PostgreSQL tools:

1.  `list_views`:
- Add a new optional `"schema_name"` filter parameter to return results
based on a specific schema name pattern.
- Add an additional column `"definition"` to return the view definition.
2.  `list_schemas`:
- Add a new optional `"owner"` filter parameter to return results based
on a specific owner name pattern.
- Add a new optional `"limit"` parameter to return a specific number of
rows.
3.  `list_indexes`:
- Add a new optional `"only_unused"` filter parameter to return only
unused indexes.

> Should include a concise description of the changes (bug or feature),
it's
> impact, along with a summary of the solution

list_views
<img width="1531" height="763" alt="Screenshot 2025-11-25 at 1 36 39 PM"
src="https://github.com/user-attachments/assets/bd6805b3-43d2-46c7-adc8-62d3a4521d36"
/>

list_schemas
<img width="1519" height="755" alt="Screenshot 2025-11-25 at 1 35 54 PM"
src="https://github.com/user-attachments/assets/62d3e987-b64e-442b-ba1a-84def1df7a58"
/>


list_indexes
<img width="1523" height="774" alt="Screenshot 2025-11-25 at 1 35 32 PM"
src="https://github.com/user-attachments/assets/c6f73b3f-f8a2-4b76-9218-64d7011a2241"
/>


## PR Checklist

> Thank you for opening a Pull Request! Before submitting your PR, there
are a
> few things you can do to make sure it goes smoothly:

- [x] Make sure you reviewed

[CONTRIBUTING.md](https://github.com/googleapis/genai-toolbox/blob/main/CONTRIBUTING.md)
- [x] Make sure to open an issue as a

[bug/issue](https://github.com/googleapis/genai-toolbox/issues/new/choose)
  before writing your code! That way we can discuss the change, evaluate
  designs, and agree on the general idea
- [x] Ensure the tests and linter pass
- [x] Code coverage does not decrease (if any source code was changed)
- [x] Appropriate docs were updated (if necessary)
- [x] Make sure to add `!` if this involve a breaking change

🛠️ Fixes #<1738>

Co-authored-by: Averi Kitsch <akitsch@google.com>
This commit is contained in:
Srividya Reddy
2025-12-10 01:46:45 +05:30
committed by GitHub
parent 32367a472f
commit 489117d747
14 changed files with 195 additions and 117 deletions

View File

@@ -21,12 +21,10 @@ any of the following sources:
`postgres-list-indexes` lists detailed information as JSON for indexes. The tool
takes the following input parameters:
- `table_name` (optional): A text to filter results by table name. The input is
used within a LIKE clause. Default: `""`
- `index_name` (optional): A text to filter results by index name. The input is
used within a LIKE clause. Default: `""`
- `schema_name` (optional): A text to filter results by schema name. The input
is used within a LIKE clause. Default: `""`
- `table_name` (optional): A text to filter results by table name. Default: `""`
- `index_name` (optional): A text to filter results by index name. Default: `""`
- `schema_name` (optional): A text to filter results by schema name. Default: `""`
- `only_unused` (optional): If true, returns indexes that have never been used.
- `limit` (optional): The maximum number of rows to return. Default: `50`.
## Example

View File

@@ -21,9 +21,9 @@ the following sources:
`postgres-list-schemas` lists detailed information as JSON for each schema. The
tool takes the following input parameters:
- `schema_name` (optional): A pattern to filter schema names using SQL LIKE
operator.
If omitted, all user-defined schemas are returned.
- `schema_name` (optional): A text to filter results by schema name. Default: `""`
- `owner` (optional): A text to filter results by owner name. Default: `""`
- `limit` (optional): The maximum number of rows to return. Default: `50`.
## Example

View File

@@ -20,9 +20,9 @@ Postgres database. It's compatible with any of the following sources:
`postgres-list-sequences` lists detailed information as JSON for all sequences.
The tool takes the following input parameters:
- `sequencename` (optional): A text to filter results by sequence name. The
- `sequence_name` (optional): A text to filter results by sequence name. The
input is used within a LIKE clause. Default: `""`
- `schemaname` (optional): A text to filter results by schema name. The input is
- `schema_name` (optional): A text to filter results by schema name. The input is
used within a LIKE clause. Default: `""`
- `limit` (optional): The maximum number of rows to return. Default: `50`.
@@ -45,9 +45,9 @@ The response is a json array with the following elements:
```json
{
"sequencename": "sequence name",
"schemaname": "schema name",
"sequenceowner": "owner of the sequence",
"sequence_name": "sequence name",
"schema_name": "schema name",
"sequence_owner": "owner of the sequence",
"data_type": "data type of the sequence",
"start_value": "starting value of the sequence",
"min_value": "minimum value of the sequence",

View File

@@ -19,11 +19,11 @@ a Postgres database, excluding those in system schemas (`pg_catalog`,
- [postgres](../../sources/postgres.md)
`postgres-list-views` lists detailed view information (schemaname, viewname,
ownername) as JSON for views in a database. The tool takes the following input
ownername, definition) as JSON for views in a database. The tool takes the following input
parameters:
- `viewname` (optional): A string pattern to filter view names. The search uses
SQL LIKE operator to filter the views. Default: `""`
- `view_name` (optional): A string pattern to filter view names. Default: `""`
- `schema_name` (optional): A string pattern to filter schema names. Default: `""`
- `limit` (optional): The maximum number of rows to return. Default: `50`.
## Example

View File

@@ -98,11 +98,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
}
allParameters := parameters.Parameters{}
description := cfg.Description
if description == "" {
description = "Fetches the current state of the PostgreSQL server, returning the version, whether it's a replica, uptime duration, maximum connection limit, number of current connections, number of active connections, and the percentage of connections in use."
if cfg.Description == "" {
cfg.Description = "Fetches the current state of the PostgreSQL server, returning the version, whether it's a replica, uptime duration, maximum connection limit, number of current connections, number of active connections, and the percentage of connections in use."
}
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters, nil)
// finish tool setup
return Tool{
@@ -134,7 +133,13 @@ func (t Tool) ToConfig() tools.ToolConfig {
}
func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) {
sliceParams := params.AsSlice()
paramsMap := params.AsMap()
newParams, err := parameters.GetParams(t.allParams, paramsMap)
if err != nil {
return nil, fmt.Errorf("unable to extract standard params %w", err)
}
sliceParams := newParams.AsSlice()
results, err := t.pool.Query(ctx, databaseOverviewStatement, sliceParams...)
if err != nil {

View File

@@ -59,7 +59,8 @@ const listIndexesStatement = `
ON i.oid = s.indexrelid
WHERE
t.relkind = 'r'
AND s.schemaname NOT IN ('pg_catalog', 'information_schema')
AND s.schemaname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
AND s.schemaname NOT LIKE 'pg_temp_%'
)
SELECT *
FROM IndexDetails
@@ -67,11 +68,12 @@ const listIndexesStatement = `
($1::text IS NULL OR schema_name LIKE '%' || $1 || '%')
AND ($2::text IS NULL OR table_name LIKE '%' || $2 || '%')
AND ($3::text IS NULL OR index_name LIKE '%' || $3 || '%')
AND ($4::boolean IS NOT TRUE OR is_used IS FALSE)
ORDER BY
schema_name,
table_name,
index_name
LIMIT COALESCE($4::int, 50);
LIMIT COALESCE($5::int, 50);
`
func init() {
@@ -131,13 +133,14 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
parameters.NewStringParameterWithDefault("schema_name", "", "Optional: a text to filter results by schema name. The input is used within a LIKE clause."),
parameters.NewStringParameterWithDefault("table_name", "", "Optional: a text to filter results by table name. The input is used within a LIKE clause."),
parameters.NewStringParameterWithDefault("index_name", "", "Optional: a text to filter results by index name. The input is used within a LIKE clause."),
parameters.NewBooleanParameterWithDefault("only_unused", false, "Optional: If true, only returns indexes that have never been used."),
parameters.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return. Default is 50"),
}
description := cfg.Description
if description == "" {
description = "Lists available user indexes in the database, excluding system schemas (pg_catalog, information_schema). For each index, the following properties are returned: schema name, table name, index name, index type (access method), a boolean indicating if it's a unique index, a boolean indicating if it's for a primary key, the index definition, index size in bytes, the number of index scans, the number of index tuples read, the number of table tuples fetched via index scans, and a boolean indicating if the index has been used at least once."
if cfg.Description == "" {
cfg.Description = "Lists available user indexes in the database, excluding system schemas (pg_catalog, information_schema). For each index, the following properties are returned: schema name, table name, index name, index type (access method), a boolean indicating if it's a unique index, a boolean indicating if it's for a primary key, the index definition, index size in bytes, the number of index scans, the number of index tuples read, the number of table tuples fetched via index scans, and a boolean indicating if the index has been used at least once."
}
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters, nil)
// finish tool setup
return Tool{
@@ -169,7 +172,13 @@ func (t Tool) ToConfig() tools.ToolConfig {
}
func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) {
sliceParams := params.AsSlice()
paramsMap := params.AsMap()
newParams, err := parameters.GetParams(t.allParams, paramsMap)
if err != nil {
return nil, fmt.Errorf("unable to extract standard params %w", err)
}
sliceParams := newParams.AsSlice()
results, err := t.pool.Query(ctx, listIndexesStatement, sliceParams...)
if err != nil {

View File

@@ -32,28 +32,28 @@ const kind string = "postgres-list-schemas"
const listSchemasStatement = `
WITH
schema_grants AS (
SELECT schema_oid, jsonb_object_agg(grantee, privileges) AS grants
FROM
(
SELECT
n.oid AS schema_oid,
CASE
WHEN p.grantee = 0 THEN 'PUBLIC'
ELSE pg_catalog.pg_get_userbyid(p.grantee)
END
AS grantee,
jsonb_agg(p.privilege_type ORDER BY p.privilege_type) AS privileges
FROM pg_catalog.pg_namespace n, aclexplode(n.nspacl) p
WHERE n.nspacl IS NOT NULL
GROUP BY n.oid, grantee
) permissions_by_grantee
GROUP BY schema_oid
),
all_schemas AS (
SELECT
n.nspname AS schema_name,
pg_catalog.pg_get_userbyid(n.nspowner) AS owner,
schema_grants AS (
SELECT schema_oid, jsonb_object_agg(grantee, privileges) AS grants
FROM
(
SELECT
n.oid AS schema_oid,
CASE
WHEN p.grantee = 0 THEN 'PUBLIC'
ELSE pg_catalog.pg_get_userbyid(p.grantee)
END
AS grantee,
jsonb_agg(p.privilege_type ORDER BY p.privilege_type) AS privileges
FROM pg_catalog.pg_namespace n, aclexplode(n.nspacl) p
WHERE n.nspacl IS NOT NULL
GROUP BY n.oid, grantee
) permissions_by_grantee
GROUP BY schema_oid
),
all_schemas AS (
SELECT
n.nspname AS schema_name,
pg_catalog.pg_get_userbyid(n.nspowner) AS owner,
COALESCE(sg.grants, '{}'::jsonb) AS grants,
(
SELECT COUNT(*)
@@ -67,18 +67,21 @@ const listSchemasStatement = `
) AS views,
(SELECT COUNT(*) FROM pg_catalog.pg_proc p WHERE p.pronamespace = n.oid)
AS functions
FROM pg_catalog.pg_namespace n
LEFT JOIN schema_grants sg
ON n.oid = sg.schema_oid
)
FROM pg_catalog.pg_namespace n
LEFT JOIN schema_grants sg
ON n.oid = sg.schema_oid
)
SELECT *
FROM all_schemas
-- Exclude system schemas and temporary schemas created per session.
-- Exclude system schemas and temporary schemas created per session.
WHERE
schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
AND schema_name NOT LIKE 'pg_temp_%'
AND ($1::text IS NULL OR schema_name LIKE '%' || $1::text || '%')
ORDER BY schema_name;
schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
AND schema_name NOT LIKE 'pg_temp_%'
AND schema_name NOT LIKE 'pg_toast_temp_%'
AND ($1::text IS NULL OR schema_name ILIKE '%' || $1::text || '%')
AND ($2::text IS NULL OR owner ILIKE '%' || $2::text || '%')
ORDER BY schema_name
LIMIT COALESCE($3::int, NULL);
`
func init() {
@@ -136,12 +139,14 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
allParameters := parameters.Parameters{
parameters.NewStringParameterWithDefault("schema_name", "", "Optional: A specific schema name pattern to search for."),
parameters.NewStringParameterWithDefault("owner", "", "Optional: A specific schema owner name pattern to search for."),
parameters.NewIntParameterWithDefault("limit", 10, "Optional: The maximum number of schemas to return."),
}
description := cfg.Description
if description == "" {
description = "Lists all schemas in the database ordered by schema name and excluding system and temporary schemas. It returns the schema name, schema owner, grants, number of functions, number of tables and number of views within each schema."
if cfg.Description == "" {
cfg.Description = "Lists all schemas in the database ordered by schema name and excluding system and temporary schemas. It returns the schema name, schema owner, grants, number of functions, number of tables and number of views within each schema."
}
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters, nil)
// finish tool setup
return Tool{
@@ -169,7 +174,13 @@ type Tool struct {
}
func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) {
sliceParams := params.AsSlice()
paramsMap := params.AsMap()
newParams, err := parameters.GetParams(t.allParams, paramsMap)
if err != nil {
return nil, fmt.Errorf("unable to extract standard params %w", err)
}
sliceParams := newParams.AsSlice()
results, err := t.pool.Query(ctx, listSchemasStatement, sliceParams...)
if err != nil {

View File

@@ -32,9 +32,9 @@ const kind string = "postgres-list-sequences"
const listSequencesStatement = `
SELECT
sequencename,
schemaname,
sequenceowner,
sequencename as sequence_name,
schemaname as schema_name,
sequenceowner as sequence_owner,
data_type,
start_value,
min_value,
@@ -45,7 +45,7 @@ const listSequencesStatement = `
WHERE
($1::text IS NULL OR schemaname LIKE '%' || $1 || '%')
AND ($2::text IS NULL OR sequencename LIKE '%' || $2 || '%')
ORDER BY schemaname, sequencename
ORDER BY schema_name, sequence_name
LIMIT COALESCE($3::int, 50);
`
@@ -104,15 +104,15 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
}
allParameters := parameters.Parameters{
parameters.NewStringParameterWithDefault("schemaname", "", "Optional: A specific schema name pattern to search for."),
parameters.NewStringParameterWithDefault("sequencename", "", "Optional: A specific sequence name pattern to search for."),
parameters.NewStringParameterWithDefault("schema_name", "", "Optional: A specific schema name pattern to search for."),
parameters.NewStringParameterWithDefault("sequence_name", "", "Optional: A specific sequence name pattern to search for."),
parameters.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return. Default is 50"),
}
description := cfg.Description
if description == "" {
description = "Lists sequences in the database. Returns sequence name, schema name, sequence owner, data type of the sequence, starting value, minimum value, maximum value of the sequence, the value by which the sequence is incremented, and the last value generated by the sequence in the current session"
if cfg.Description == "" {
cfg.Description = "Lists sequences in the database. Returns sequence name, schema name, sequence owner, data type of the sequence, starting value, minimum value, maximum value of the sequence, the value by which the sequence is incremented, and the last value generated by the sequence in the current session"
}
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters, nil)
// finish tool setup
return Tool{
@@ -144,7 +144,13 @@ func (t Tool) ToConfig() tools.ToolConfig {
}
func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) {
sliceParams := params.AsSlice()
paramsMap := params.AsMap()
newParams, err := parameters.GetParams(t.allParams, paramsMap)
if err != nil {
return nil, fmt.Errorf("unable to extract standard params %w", err)
}
sliceParams := newParams.AsSlice()
results, err := t.pool.Query(ctx, listSequencesStatement, sliceParams...)
if err != nil {

View File

@@ -135,11 +135,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
parameters.NewStringParameterWithDefault("table_name", "", "Optional: A specific table name pattern to search for."),
parameters.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return."),
}
description := cfg.Description
if description == "" {
description = "Lists all non-internal triggers in a database. Returns trigger name, schema name, table name, whether its enabled or disabled, timing (e.g BEFORE/AFTER of the event), the events that cause the trigger to fire such as INSERT, UPDATE, or DELETE, whether the trigger activates per ROW or per STATEMENT, the handler function executed by the trigger and full definition."
if cfg.Description == "" {
cfg.Description = "Lists all non-internal triggers in a database. Returns trigger name, schema name, table name, whether its enabled or disabled, timing (e.g BEFORE/AFTER of the event), the events that cause the trigger to fire such as INSERT, UPDATE, or DELETE, whether the trigger activates per ROW or per STATEMENT, the handler function executed by the trigger and full definition."
}
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters, nil)
// finish tool setup
return Tool{
@@ -171,7 +171,13 @@ func (t Tool) ToConfig() tools.ToolConfig {
}
func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) {
sliceParams := params.AsSlice()
paramsMap := params.AsMap()
newParams, err := parameters.GetParams(t.allParams, paramsMap)
if err != nil {
return nil, fmt.Errorf("unable to extract standard params %w", err)
}
sliceParams := newParams.AsSlice()
results, err := t.pool.Query(ctx, listTriggersStatement, sliceParams...)
if err != nil {

View File

@@ -31,13 +31,24 @@ import (
const kind string = "postgres-list-views"
const listViewsStatement = `
SELECT schemaname, viewname, viewowner
FROM pg_views
WHERE
schemaname NOT IN ('pg_catalog', 'information_schema')
AND ($1::text IS NULL OR viewname LIKE '%' || $1::text || '%')
ORDER BY viewname
LIMIT COALESCE($2::int, 50);
WITH list_views AS (
SELECT
schemaname AS schema_name,
viewname AS view_name,
viewowner AS owner_name,
definition
FROM pg_views
)
SELECT *
FROM list_views
WHERE
schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
AND schema_name NOT LIKE 'pg_temp_%'
AND ($1::text IS NULL OR view_name ILIKE '%' || $1::text || '%')
AND ($2::text IS NULL OR schema_name ILIKE '%' || $2::text || '%')
ORDER BY
schema_name, view_name
LIMIT COALESCE($3::int, 50);
`
func init() {
@@ -94,15 +105,15 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
}
allParameters := parameters.Parameters{
parameters.NewStringParameterWithDefault("viewname", "", "Optional: A specific view name to search for."),
parameters.NewStringParameterWithDefault("view_name", "", "Optional: A specific view name to search for."),
parameters.NewStringParameterWithDefault("schema_name", "", "Optional: A specific schema name to search for."),
parameters.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return."),
}
paramManifest := allParameters.Manifest()
description := cfg.Description
if description == "" {
description = "Lists views in the database from pg_views with a default limit of 50 rows. Returns schemaname, viewname and the ownername."
if cfg.Description == "" {
cfg.Description = "Lists views in the database from pg_views with a default limit of 50 rows. Returns schemaname, viewname, ownername and the definition."
}
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters, nil)
// finish tool setup
return Tool{

View File

@@ -181,7 +181,7 @@ func TestAlloyDBPgToolEndpoints(t *testing.T) {
// Run Postgres prebuilt tool tests
tests.RunPostgresListTablesTest(t, tableNameParam, tableNameAuth, AlloyDBPostgresUser)
tests.RunPostgresListViewsTest(t, ctx, pool, tableNameParam)
tests.RunPostgresListViewsTest(t, ctx, pool)
tests.RunPostgresListSchemasTest(t, ctx, pool)
tests.RunPostgresListActiveQueriesTest(t, ctx, pool)
tests.RunPostgresListAvailableExtensionsTest(t)

View File

@@ -165,7 +165,7 @@ func TestCloudSQLPgSimpleToolEndpoints(t *testing.T) {
// Run Postgres prebuilt tool tests
tests.RunPostgresListTablesTest(t, tableNameParam, tableNameAuth, CloudSQLPostgresUser)
tests.RunPostgresListViewsTest(t, ctx, pool, tableNameParam)
tests.RunPostgresListViewsTest(t, ctx, pool)
tests.RunPostgresListSchemasTest(t, ctx, pool)
tests.RunPostgresListActiveQueriesTest(t, ctx, pool)
tests.RunPostgresListAvailableExtensionsTest(t)

View File

@@ -144,7 +144,7 @@ func TestPostgres(t *testing.T) {
// Run Postgres prebuilt tool tests
tests.RunPostgresListTablesTest(t, tableNameParam, tableNameAuth, PostgresUser)
tests.RunPostgresListViewsTest(t, ctx, pool, tableNameParam)
tests.RunPostgresListViewsTest(t, ctx, pool)
tests.RunPostgresListSchemasTest(t, ctx, pool)
tests.RunPostgresListActiveQueriesTest(t, ctx, pool)
tests.RunPostgresListAvailableExtensionsTest(t)

View File

@@ -1260,8 +1260,8 @@ func RunPostgresListTablesTest(t *testing.T, tableNameParam, tableNameAuth, user
}
}
func setUpPostgresViews(t *testing.T, ctx context.Context, pool *pgxpool.Pool, viewName, tableName string) func() {
createView := fmt.Sprintf("CREATE VIEW %s AS SELECT name FROM %s", viewName, tableName)
func setUpPostgresViews(t *testing.T, ctx context.Context, pool *pgxpool.Pool, viewName string) func() {
createView := fmt.Sprintf("CREATE VIEW %s AS SELECT 1 AS col", viewName)
_, err := pool.Exec(ctx, createView)
if err != nil {
t.Fatalf("failed to create view: %v", err)
@@ -1275,9 +1275,10 @@ func setUpPostgresViews(t *testing.T, ctx context.Context, pool *pgxpool.Pool, v
}
}
func RunPostgresListViewsTest(t *testing.T, ctx context.Context, pool *pgxpool.Pool, tableName string) {
viewName1 := "test_view_1" + strings.ReplaceAll(uuid.New().String(), "-", "")
dropViewfunc1 := setUpPostgresViews(t, ctx, pool, viewName1, tableName)
func RunPostgresListViewsTest(t *testing.T, ctx context.Context, pool *pgxpool.Pool) {
//adding this line temporarily
viewName := "test_view_" + strings.ReplaceAll(uuid.New().String(), "-", "")
dropViewfunc1 := setUpPostgresViews(t, ctx, pool, viewName)
defer dropViewfunc1()
invokeTcs := []struct {
@@ -1288,13 +1289,13 @@ func RunPostgresListViewsTest(t *testing.T, ctx context.Context, pool *pgxpool.P
}{
{
name: "invoke list_views with newly created view",
requestBody: bytes.NewBuffer([]byte(fmt.Sprintf(`{"viewname": "%s"}`, viewName1))),
requestBody: bytes.NewBuffer([]byte(fmt.Sprintf(`{"view_name": "%s"}`, viewName))),
wantStatusCode: http.StatusOK,
want: fmt.Sprintf(`[{"schemaname":"public","viewname":"%s","viewowner":"postgres"}]`, viewName1),
want: fmt.Sprintf(`[{"schema_name":"public","view_name":"%s","owner_name":"postgres","definition":" SELECT 1 AS col;"}]`, viewName),
},
{
name: "invoke list_views with non-existent_view",
requestBody: bytes.NewBuffer([]byte(`{"viewname": "non_existent_view"}`)),
requestBody: bytes.NewBuffer([]byte(`{"view_name": "non_existent_view"}`)),
wantStatusCode: http.StatusOK,
want: `null`,
},
@@ -1350,6 +1351,7 @@ func RunPostgresListSchemasTest(t *testing.T, ctx context.Context, pool *pgxpool
requestBody io.Reader
wantStatusCode int
want []map[string]any
compareSubset bool
}{
{
name: "invoke list_schemas with schema_name",
@@ -1357,6 +1359,19 @@ func RunPostgresListSchemasTest(t *testing.T, ctx context.Context, pool *pgxpool
wantStatusCode: http.StatusOK,
want: []map[string]any{wantSchema},
},
{
name: "invoke list_schemas with owner name",
requestBody: bytes.NewBuffer([]byte(fmt.Sprintf(`{"owner": "%s"}`, "postgres"))),
wantStatusCode: http.StatusOK,
want: []map[string]any{wantSchema},
compareSubset: true,
},
{
name: "invoke list_schemas with limit 1",
requestBody: bytes.NewBuffer([]byte(fmt.Sprintf(`{"schema_name": "%s","limit": 1}`, schemaName))),
wantStatusCode: http.StatusOK,
want: []map[string]any{wantSchema},
},
{
name: "invoke list_schemas with non-existent schema",
requestBody: bytes.NewBuffer([]byte(`{"schema_name": "non_existent_schema"}`)),
@@ -1392,8 +1407,25 @@ func RunPostgresListSchemasTest(t *testing.T, ctx context.Context, pool *pgxpool
t.Fatalf("failed to unmarshal nested result string: %v", err)
}
if diff := cmp.Diff(tc.want, got); diff != "" {
t.Errorf("Unexpected result (-want +got):\n%s", diff)
if tc.compareSubset {
// Assert that the 'wantTrigger' is present in the 'got' list.
found := false
for _, resultSchema := range got {
if resultSchema["schema_name"] == wantSchema["schema_name"] {
found = true
if diff := cmp.Diff(wantSchema, resultSchema); diff != "" {
t.Errorf("Mismatch in fields for the expected trigger (-want +got):\n%s", diff)
}
break
}
}
if !found {
t.Errorf("Expected schema '%s' not found in the list of all schemas.", wantSchema)
}
} else {
if diff := cmp.Diff(tc.want, got); diff != "" {
t.Errorf("Unexpected result (-want +got):\n%s", diff)
}
}
})
}
@@ -2179,15 +2211,15 @@ func RunPostgresListSequencesTest(t *testing.T, ctx context.Context, pool *pgxpo
defer teardown(t)
wantSequence := map[string]any{
"sequencename": sequenceName,
"schemaname": "public",
"sequenceowner": "postgres",
"data_type": "bigint",
"start_value": float64(1),
"min_value": float64(1),
"max_value": float64(9223372036854775807),
"increment_by": float64(1),
"last_value": nil,
"sequence_name": sequenceName,
"schema_name": "public",
"sequence_owner": "postgres",
"data_type": "bigint",
"start_value": float64(1),
"min_value": float64(1),
"max_value": float64(9223372036854775807),
"increment_by": float64(1),
"last_value": nil,
}
invokeTcs := []struct {
@@ -2199,13 +2231,13 @@ func RunPostgresListSequencesTest(t *testing.T, ctx context.Context, pool *pgxpo
}{
{
name: "invoke list_sequences",
requestBody: bytes.NewBufferString(fmt.Sprintf(`{"sequencename": "%s"}`, sequenceName)),
requestBody: bytes.NewBufferString(fmt.Sprintf(`{"sequence_name": "%s"}`, sequenceName)),
wantStatusCode: http.StatusOK,
want: []map[string]any{wantSequence},
},
{
name: "invoke list_sequences with non-existent sequence",
requestBody: bytes.NewBufferString(`{"sequencename": "non_existent_sequence"}`),
requestBody: bytes.NewBufferString(`{"sequence_name": "non_existent_sequence"}`),
wantStatusCode: http.StatusOK,
want: nil,
},