Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server: fix issue with tracking custom functions that return SETOF materialized view (close #5294) #5945

Merged
merged 19 commits into from
Oct 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ This release contains the [PDV refactor (#4111)](https://github.com/hasura/graph
- server: limit the length of event trigger names (close #5786)
**NOTE:** If you have event triggers with names greater than 42 chars, then you should update their names to avoid running into Postgres identifier limit bug (#5786)
- server: validate remote schema queries (fixes #4143)
- server: fix issue with tracking custom functions that return `SETOF` materialized view (close #5294) (#5945)
- console: allow user to cascade Postgres dependencies when dropping Postgres objects (close #5109) (#5248)
- console: mark inconsistent remote schemas in the UI (close #5093) (#5181)
- cli: add missing global flags for seed command (#5565)
Expand Down
4 changes: 2 additions & 2 deletions server/src-lib/Hasura/RQL/DDL/Schema/Function.hs
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ handleMultipleFunctions qf = \case
throw400 NotSupported $
"function " <> qf <<> " is overloaded. Overloaded functions are not supported"

fetchRawFunctioInfo :: MonadTx m => QualifiedFunction -> m RawFunctionInfo
fetchRawFunctioInfo qf@(QualifiedObject sn fn) =
fetchRawFunctionInfo :: MonadTx m => QualifiedFunction -> m RawFunctionInfo
fetchRawFunctionInfo qf@(QualifiedObject sn fn) =
handleMultipleFunctions qf =<< map (Q.getAltJ . runIdentity) <$> fetchFromDatabase
where
fetchFromDatabase = liftTx $
Expand Down
26 changes: 15 additions & 11 deletions server/src-lib/Hasura/SQL/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -195,30 +195,34 @@ instance ToTxt TableName where
data TableType
= TTBaseTable
| TTView
| TTMaterializedView
| TTForeignTable
| TTLocalTemporary
deriving (Eq)

tableTyToTxt :: TableType -> T.Text
tableTyToTxt TTBaseTable = "BASE TABLE"
tableTyToTxt TTView = "VIEW"
tableTyToTxt TTForeignTable = "FOREIGN TABLE"
tableTyToTxt TTLocalTemporary = "LOCAL TEMPORARY"
tableTyToTxt TTBaseTable = "BASE TABLE"
tableTyToTxt TTView = "VIEW"
tableTyToTxt TTMaterializedView = "MATERIALIZED VIEW"
tableTyToTxt TTForeignTable = "FOREIGN TABLE"
tableTyToTxt TTLocalTemporary = "LOCAL TEMPORARY"
kolharsam marked this conversation as resolved.
Show resolved Hide resolved

instance Show TableType where
show = T.unpack . tableTyToTxt

instance Q.FromCol TableType where
fromCol bs = flip Q.fromColHelper bs $ PD.enum $ \case
"BASE TABLE" -> Just TTBaseTable
"VIEW" -> Just TTView
"FOREIGN TABLE" -> Just TTForeignTable
"LOCAL TEMPORARY" -> Just TTLocalTemporary
_ -> Nothing
"BASE TABLE" -> Just TTBaseTable
"VIEW" -> Just TTView
"MATERIALIZED VIEW" -> Just TTMaterializedView
"FOREIGN TABLE" -> Just TTForeignTable
"LOCAL TEMPORARY" -> Just TTLocalTemporary
_ -> Nothing

isView :: TableType -> Bool
isView TTView = True
isView _ = False
isView TTView = True
isView TTMaterializedView = True
isView _ = False

newtype ConstraintName
= ConstraintName { getConstraintTxt :: T.Text }
Expand Down
2 changes: 1 addition & 1 deletion server/src-rsr/catalog_version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
39
40
57 changes: 33 additions & 24 deletions server/src-rsr/initialise.sql
Original file line number Diff line number Diff line change
Expand Up @@ -568,33 +568,42 @@ CREATE VIEW hdb_catalog.hdb_function_info_agg AS (
(
SELECT
e
FROM
(
FROM
(
SELECT
description,
has_variadic,
function_type,
return_type_schema,
return_type_name,
return_type_type,
returns_set,
input_arg_types,
input_arg_names,
default_args,
exists(
SELECT
description,
has_variadic,
function_type,
return_type_schema,
return_type_name,
return_type_type,
returns_set,
input_arg_types,
input_arg_names,
default_args,
exists(
SELECT
1
FROM
information_schema.tables
WHERE
table_schema = return_type_schema
AND table_name = return_type_name
) AS returns_table
) AS e
1
FROM
information_schema.tables
WHERE
table_schema = return_type_schema
AND table_name = return_type_name
)
OR exists(
SELECT
1
FROM
pg_matviews
WHERE
schemaname = return_type_schema
AND matviewname = return_type_name
) AS returns_table
) AS e
)
) AS "function_info"
FROM
hdb_catalog.hdb_function_agg
FROM
hdb_catalog.hdb_function_agg
);

CREATE OR REPLACE FUNCTION
Expand Down
46 changes: 46 additions & 0 deletions server/src-rsr/migrations/39_to_40.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
CREATE
OR REPLACE VIEW hdb_catalog.hdb_function_info_agg AS (
SELECT
function_name,
function_schema,
row_to_json (
(
SELECT
e
FROM
(
SELECT
description,
has_variadic,
function_type,
return_type_schema,
return_type_name,
return_type_type,
returns_set,
input_arg_types,
input_arg_names,
default_args,
exists(
SELECT
1
FROM
information_schema.tables
WHERE
table_schema = return_type_schema
AND table_name = return_type_name
)
OR exists(
SELECT
1
FROM
pg_matviews
WHERE
schemaname = return_type_schema
AND matviewname = return_type_name
) AS returns_table
) AS e
)
) AS "function_info"
FROM
hdb_catalog.hdb_function_agg
);
37 changes: 37 additions & 0 deletions server/src-rsr/migrations/40_to_39.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
CREATE
OR REPLACE VIEW hdb_catalog.hdb_function_info_agg AS (
SELECT
function_name,
function_schema,
row_to_json (
(
SELECT
e
FROM
(
SELECT
description,
has_variadic,
function_type,
return_type_schema,
return_type_name,
return_type_type,
returns_set,
input_arg_types,
input_arg_names,
default_args,
exists(
SELECT
1
FROM
information_schema.tables
WHERE
table_schema = return_type_schema
AND table_name = return_type_name
) AS returns_table
) AS e
)
) AS "function_info"
FROM
hdb_catalog.hdb_function_agg
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
description: Custom GraphQL query using search_author_mview function which returns results from a materialized view
url: /v1/graphql
status: 200
response:
data:
search_author_mview:
- first_name: franz
last_name: kafka
query:
query: |
query {
search_author_mview(
args: {query: "kafka"}
) {
first_name
last_name
}
}
42 changes: 42 additions & 0 deletions server/tests-py/queries/graphql_query/functions/setup.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,45 @@ args:
name: get_session_var
configuration:
session_argument: hasura_session

# track & query functions that return SETOF materialized views
- type: run_sql
args:
sql: |
CREATE TABLE author(
id SERIAL PRIMARY KEY,
first_name TEXT,
last_name TEXT
);

INSERT INTO author(first_name, last_name) VALUES
('enid', 'blyton'),
('ruskin', 'bond'),
('franz', 'kafka');

CREATE MATERIALIZED VIEW author_mat_view AS
SELECT * FROM author;

CREATE FUNCTION search_author_mview(query text)
RETURNS SETOF author_mat_view AS $FUNCTION$
SELECT * FROM author_mat_view WHERE
first_name = query OR
last_name = query
$FUNCTION$ LANGUAGE sql STABLE;

- type: track_table
args:
name: author
schema: public

- type: track_table
args:
name: author_mat_view
schema: public

- type: track_function
version: 2
args:
function:
schema: public
name: search_author_mview
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ args:
DROP TABLE integer_column cascade;
DROP TABLE "user" cascade;
DROP TABLE text_result cascade;
DROP TABLE author cascade;
DROP MATERIALIZED VIEW IF EXISTS author_mat_view cascade;
kolharsam marked this conversation as resolved.
Show resolved Hide resolved
cascade: true
4 changes: 4 additions & 0 deletions server/tests-py/test_graphql_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,10 @@ def test_track_function_v2_errors(self, hge_ctx):
@pytest.mark.parametrize("transport", ['http', 'websocket'])
def test_query_get_test_session_id(self, hge_ctx, transport):
check_query_f(hge_ctx, self.dir() + '/query_get_test_session_id.yaml')

@pytest.mark.parametrize("transport", ['http', 'websocket'])
def test_query_search_author_mview(self, hge_ctx, transport):
check_query_f(hge_ctx, self.dir() + '/query_search_author_mview.yaml')

@classmethod
def dir(cls):
Expand Down