Skip to content

ExternalFunction names leave out argument types, so Snowflake rejects GRANT OWNERSHIP on them #85

Description

@GClunies

Problem

ExternalFunction.fqn has no argument types. The UDF classes (JavascriptUDF, PythonUDF) add them through udf_fqn in snowcap/resources/function.py. Snowflake identifies a function by its name and its argument types, so statements that name an external function need the signature.

Example: a config declares an external function with one VARCHAR argument, and gives it a new owner. Snowcap plans a transfer and sends:

GRANT OWNERSHIP ON FUNCTION MY_DB.MY_SCHEMA.MY_FN TO ROLE NEW_OWNER COPY CURRENT GRANTS

Snowflake rejects it:

090208 (42601): Argument types of function must be specified.

The statement Snowflake expects is:

GRANT OWNERSHIP ON FUNCTION MY_DB.MY_SCHEMA.MY_FN(VARCHAR) TO ROLE NEW_OWNER COPY CURRENT GRANTS

How to reproduce

from snowcap.enums import ResourceType
from snowcap.identifiers import URN
from snowcap.lifecycle import transfer_resource
from snowcap.resources import ExternalFunction

fn = ExternalFunction(
    name="MY_FN", database="MY_DB", schema="MY_SCHEMA",
    args=[{"name": "x", "data_type": "VARCHAR"}], returns="VARIANT",
    api_integration="MY_API", as_="https://example.com/x",
)
print(fn.fqn)  # MY_DB.MY_SCHEMA.MY_FN, with no (VARCHAR)
print(transfer_resource(URN.from_resource(fn, account_locator="ABC123"), "NEW_OWNER", ResourceType.ROLE, copy_current_grants=True))

Scope

Not verified: other statements that name an external function, for example a drop or a privilege grant, can have the same problem. A fix changes how Snowcap identifies an external function, so it can also change how a plan matches it to live state. Two functions with the same name and different signatures are a case to test.

Context

Found during review of #84. That PR fixes the object type only (EXTERNAL FUNCTION becomes FUNCTION), not the name.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions