Compare commits

...

18 Commits
v1.0.0 ... main

Author SHA1 Message Date
Shah Newaz Khan
fb20f8e47a
Merge pull request #9 from FlipsideCrypto/STREAM-1089/namespace-scope-construct_api_route
namespace scope construct_api_route
2025-04-11 07:57:53 -07:00
shah
84dc724d7d namespace scope construct_api_route 2025-04-10 19:32:40 -07:00
Shah Newaz Khan
6a45354247
Merge pull request #8 from FlipsideCrypto/STREAM-1089/namespace-scope-ephemeral-deploy-macros
namespace scope ephemeral deploy macro dependencies | add render macro
2025-04-10 15:51:45 -07:00
shah
732e561c71 namesapace scope apply_grants_by_schema() 2025-04-09 16:32:02 -07:00
shah
42c83595f8 namespace scope ephemeral deploy macro dependencies 2025-04-09 13:58:58 -07:00
Shah Newaz Khan
d60977ef9a
Merge pull request #6 from FlipsideCrypto/STREAM-1161/fix-generic-tests
add udf_test fix
2025-03-24 22:48:54 -07:00
shah
9fdafb40c8 fix typo in test doc string 2025-03-14 10:44:23 -07:00
shah
f8f3e42e6b add udf_test fix 2025-03-14 09:50:08 -07:00
Shah Newaz Khan
5415e41208
Merge pull request #5 from FlipsideCrypto/STREAM-1175/remove-unused-gha
remove unused gha
2025-03-05 19:21:29 -08:00
shah
b1c1b02eb0 deprecate selectors.yml 2025-03-05 16:25:22 -08:00
shah
52e5a45053 remove unused gha 2025-03-05 16:22:57 -08:00
Jensen Yap
fdb3b04c85
Fix: update workflow upload artifact to v4 2025-03-03 12:09:59 +09:00
Jensen Yap
884d6171cd
Merge pull request #4 from FlipsideCrypto/STREAM-1156/fix-null-as-default
[STREAM-1156] Replace empty dict with NULL in API calls
2025-02-25 11:17:36 +09:00
Jensen Yap
b621a20475 Update live.yaml.sql macro: Replace empty dict with NULL in API calls 2025-02-25 11:09:39 +09:00
Shah Newaz Khan
006980d40f
Merge pull request #2 from FlipsideCrypto/STREAM-1111/fsc_utils_components_abstraction
Stream 1111/fsc utils components abstraction
2024-12-09 18:58:10 -08:00
shah
c92ab027df remove analysis/generate_test_udf_skeletorn 2024-12-09 10:32:05 -08:00
shah
09fb64fcbe rename model:livequery-models -> livequery-base 2024-12-09 10:24:44 -08:00
shah
2e821cb0f7 remove marketplace macros 2024-12-06 19:09:11 -08:00
13 changed files with 151 additions and 268 deletions

View File

@ -51,7 +51,7 @@ jobs:
${{ inputs.command }}
- name: Store logs
if: always()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: logs-${{ inputs.environment }}-${{ github.run_number }}-${{ github.run_attempt }}
path: |

View File

@ -1,28 +0,0 @@
name: integration test
run-name: ${{ github.event.inputs.branch }}
on:
workflow_dispatch:
schedule:
# Runs “Daily at midnight GMT” (see https://crontab.guru)
- cron: '0 0 * * *'
concurrency: ${{ github.workflow }}
jobs:
test:
name: ${{ matrix.environment }}
uses: ./.github/workflows/dbt.yml
secrets: inherit
strategy:
fail-fast: false
matrix:
include:
- environment: hosted
warehouse: XSMALL
- environment: prod
warehouse: DBT_CLOUD
with:
warehouse: ${{ matrix.warehouse }}
environment: ${{ matrix.environment }}
command: dbt test -s test___utils_udf_introspect

View File

@ -1,19 +0,0 @@
name: dbt_run_dev_refresh
run-name: dbt_run_dev_refresh
on:
workflow_dispatch:
schedule:
# Runs "at 9:00 UTC" (see https://crontab.guru)
- cron: '0 9 * * *'
concurrency:
group: ${{ github.workflow }}
jobs:
dev_refresh:
uses: ./.github/workflows/dbt.yml
secrets: inherit
with:
environment: prod
command: dbt run-operation run_sp_create_prod_clone

View File

@ -1,49 +0,0 @@
name: test udfs
run-name: ${{ github.event.inputs.branch }}
on:
workflow_dispatch:
inputs:
environment:
type: choice
description: DBT Run Environment
required: true
options:
- dev
- prod
- hosted
default: dev
warehouse:
type: choice
description: Snowflake warehouse
required: true
options:
- DBT
- DBT_CLOUD
- XSMALL
default: DBT
schedule:
# Runs “Daily at midnight GMT” (see https://crontab.guru)
- cron: '0 0 * * *'
concurrency:
group: ${{ github.workflow }}
jobs:
scheduled:
uses: ./.github/workflows/dbt.yml
if: github.event_name == 'schedule' || github.event_name == 'push'
secrets: inherit
with:
warehouse: ${{ vars.WAREHOUSE }}
environment: prod
command: dbt test --selector test_udfs --threads 24
dispatched:
uses: ./.github/workflows/dbt.yml
if: github.event_name == 'workflow_dispatch'
secrets: inherit
with:
warehouse: ${{ inputs.warehouse }}
environment: ${{ inputs.environment }}
command: dbt test --selector test_udfs --threads 24

View File

@ -1,45 +0,0 @@
{% set schema = "strangelove" %}
{% set config = fromyaml(config_strangelove_udfs(schema_name = schema, utils_schema_name = "quicknode_utils")) %}
{% set raw_test_queries %}
strangelove.get:
- |
'https://api.strange.love/cosmoshub/mainnet/rpc/block_by_hash'
- |
{
'blockHash': '0xD70952032620CC4E2737EB8AC379806359D8E0B17B0488F627997A0B043ABDED'
}
strangelove.post:
- |
'https://endpoint'
- |
{
'foo': 'bar'
}
{% endset %}
{% set test_queries = fromyaml(raw_test_queries) %}
{{ test_queries }}
{{ schema }}
_____
columns:
{%- for item in config %}
- name: {{ item["name"] | replace(schema~".", "") }}
tests:
- test_marketplace_udf:
name: test_{{ item["name"].replace(".", "__") ~ "_status_200" }}
args: >
{{ test_queries[item["name"]] | join(", ") | indent(16) }}
validations:
- result:status_code = 200
{%- endfor %}
=====================
{{ config | pprint}}
{# {% for item in config %}
{% if item["return_type"][0] != "VARIANT"%}
{{ item["return_type"][0] }}
{% endif %}
{% endfor %} #}

View File

@ -1,3 +0,0 @@
{{crud_udfs_by_chain(config_evm_high_level_abstractions, 'ethereum', 'mainnet', false)}}
{{- crud_udfs_by_chain(config_evm_rpc_primitives, "ethereum", None, False) -}}
{{- crud_udfs_by_chain(config_evm_rpc_primitives, "ethereum", None, true) -}}

View File

@ -25,7 +25,7 @@ clean-targets: # directories to be removed by `dbt clean`
- "dbt_packages"
models:
livequery_models:
livequery_base:
deploy:
+materialized: ephemeral
core:
@ -34,20 +34,13 @@ models:
+enabled: '{{ true if env_var("ENABLE_SNOWFLAKE_SECRETS", "") else false }}'
evm:
+tags: evm
marketplace:
+tags: marketplace
tests:
+store_failures: true # all tests
livequery_models:
deploy:
marketplace:
blockpour:
# TODO: enable tests for blockpour once we get an API key
+enabled: false
seeds:
+enabled: "{{ target.name not in ['livequery', 'livequery_dev'] }}"
+enabled: "{{ target.database not in ['livequery', 'livequery_dev'] }}"
on-run-start:
- "{{ create_sps() }}"
@ -67,8 +60,8 @@ vars:
UPDATE_UDFS_AND_SPS: false
DROP_UDFS_AND_SPS: false
UPDATE_SNOWFLAKE_TAGS: true
STREAMLINE_INVOKE_STREAMS: False
STREAMLINE_USE_DEV_FOR_EXTERNAL_TABLES: False
STREAMLINE_INVOKE_STREAMS: false
STREAMLINE_USE_DEV_FOR_EXTERNAL_TABLES: false
STUDIO_TEST_USER_ID: '{{ env_var("STUDIO_TEST_USER_ID", "98d15c30-9fa5-43cd-9c69-3d4c0bb269f5") }}'
API_INTEGRATION: '{{ var("config")[target.name]["API_INTEGRATION"] }}'

View File

@ -86,7 +86,7 @@
'GET',
url,
{},
{},
NULL,
_utils.UDF_WHOAMI(),
''
)
@ -103,7 +103,7 @@
'GET',
url,
{},
{},
NULL,
_utils.UDF_WHOAMI(),
secret_name
)
@ -131,4 +131,4 @@
VOLATILE
COMMENT = $$Returns a list of allowed domains.$$
sql: allowed
{% endmacro %}
{% endmacro %}

View File

@ -36,7 +36,7 @@
func_type = none
) %}
CREATE OR REPLACE {{ func_type }} FUNCTION {{ name_ }}(
{{- compile_signature(signature) }}
{{- livequery_base.compile_signature(signature) }}
)
COPY GRANTS
RETURNS {{ return_type }}
@ -45,7 +45,7 @@
{% endif %}
{%- if api_integration -%}
api_integration = {{ api_integration }}
AS {{ construct_api_route(sql_) ~ ";" }}
AS {{ livequery_base.construct_api_route(sql_) ~ ";" }}
{% else -%}
AS
$$
@ -67,7 +67,7 @@
{% set func_type = config ["func_type"] %}
{% if not drop_ -%}
{{ create_sql_function(
{{ livequery_base.create_sql_function(
name_ = name_,
signature = signature,
return_type = return_type,
@ -113,40 +113,10 @@
CREATE SCHEMA IF NOT EXISTS {{ schema }};
{%- set configs = fromyaml(config_func(blockchain, network)) if network else fromyaml(config_func(schema, blockchain)) -%}
{%- for udf in configs -%}
{{- create_or_drop_function_from_config(udf, drop_=drop_) -}}
{{- livequery_base.create_or_drop_function_from_config(udf, drop_=drop_) -}}
{%- endfor -%}
{%- endmacro -%}
{% macro crud_udfs_by_marketplace(config_func, schema, utility_schema, drop_) %}
{#
Generate create or drop statements for a list of udf configs for a given blockchain and network
config_func: function that returns a list of udf configs
schema: schema name
utility_schema: utility schema name
#}
CREATE SCHEMA IF NOT EXISTS {{ schema }};
{%- set configs = fromyaml(config_func(schema, utility_schema)) if utility_schema else fromyaml(config_func(schema, schema)) -%}
{%- for udf in configs -%}
{{- create_or_drop_function_from_config(udf, drop_=drop_) -}}
{%- endfor -%}
{%- endmacro -%}
{% macro crud_marketplace_udfs(config_func, schemaName, base_api_schema_name, drop_) %}
{#
Generate create or drop statements for a list of udf configs for a given schema and api
config_func: function that returns a list of udf configs
schemaName: the target schema to build the udfs
base_api_schema_name: the schema that contains base api functions
drop_: whether to drop or create the udfs
#}
{%- set udfs = fromyaml(config_func(schemaName, base_api_schema_name)) -%}
{%- for udf in udfs -%}
{{- create_or_drop_function_from_config(udf, drop_=drop_) -}}
{%- endfor -%}
{%- endmacro -%}
{% macro ephemeral_deploy_core(config) %}
{#
This macro is used to deploy functions using ephemeral models.
@ -177,7 +147,7 @@
{% if execute and (var("UPDATE_UDFS_AND_SPS") or var("DROP_UDFS_AND_SPS")) and model.unique_id in selected_resources %}
{% set sql %}
{% for config in configs %}
{{- crud_udfs_by_chain(config, blockchain, network, var("DROP_UDFS_AND_SPS")) -}}
{{- livequery_base.crud_udfs_by_chain(config, blockchain, network, var("DROP_UDFS_AND_SPS")) -}}
{%- endfor -%}
{%- endset -%}
{%- if var("DROP_UDFS_AND_SPS") -%}
@ -185,31 +155,9 @@
{%- else -%}
{%- do log("Deploy partner udfs: " ~ this.database ~ "." ~ schema, true) -%}
{%- endif -%}
{%- do run_query(sql ~ apply_grants_by_schema(schema)) -%}
{%- do run_query(sql ~ livequery_base.apply_grants_by_schema(schema)) -%}
{%- endif -%}
SELECT '{{ model.schema }}' as schema_
{%- endmacro -%}
{% macro ephemeral_deploy_marketplace(configs) %}
{#
This macro is used to deploy functions using ephemeral models.
It should only be used within an ephemeral model.
#}
{%- set schema = this.schema -%}
{%- set utility_schema = this.identifier -%}
{% if execute and (var("UPDATE_UDFS_AND_SPS") or var("DROP_UDFS_AND_SPS")) and model.unique_id in selected_resources %}
{% set sql %}
{% for config in configs %}
{{- crud_udfs_by_marketplace(config, schema, utility_schema, var("DROP_UDFS_AND_SPS")) -}}
{%- endfor -%}
{%- endset -%}
{%- if var("DROP_UDFS_AND_SPS") -%}
{%- do log("Drop marketplace udfs: " ~ this.database ~ "." ~ schema, true) -%}
{%- else -%}
{%- do log("Deploy marketplace udfs: " ~ this.database ~ "." ~ schema, true) -%}
{%- endif -%}
{%- do run_query(sql ~ apply_grants_by_schema(schema)) -%}
{%- endif -%}
SELECT '{{ model.schema }}' as schema_
{%- endmacro -%}

View File

@ -0,0 +1,67 @@
{% macro get_rendered_model(package_name, model_name, schema, blockchain, network) %}
{#
This macro retrieves and renders a specified model from the graph.
Args:
package_name (str): The name of the package containing the model.
model_name (str): The name of the model to be rendered.
schema (str): The schema to be used.
blockchain (str): The blockchain to be used.
network (str): The network to be used.
Returns:
str: The rendered SQL of the specified model.
#}
{% if execute %}
{{ log("=== Starting get_rendered_model ===", info=True) }}
{# Use a list to store the node to avoid scope issues #}
{%- set nodes = [] -%}
{{ log("Looking for node: " ~ package_name ~ "." ~ model_name, info=True) }}
{%- for node in graph.nodes.values() -%}
{%- if node.package_name == package_name and node.name == model_name -%}
{{ log("Found target node: " ~ node.unique_id, info=True) }}
{%- do nodes.append(node) -%}
{%- endif -%}
{%- endfor -%}
{%- if nodes | length == 0 -%}
{{ log("No target node found!", info=True) }}
{{ return('') }}
{%- endif -%}
{%- set target_node = nodes[0] -%}
{{ log("Processing node: " ~ target_node.unique_id, info=True) }}
{{ log("Dependencies:\n\t\t" ~ (target_node.depends_on.nodes | pprint).replace("\n", "\n\t\t"), info=True) }}
{# First render all dependency CTEs #}
{%- set ctes = [] -%}
{%- for dep_id in target_node.depends_on.nodes -%}
{{ log("Processing dependency: " ~ dep_id, info=True) }}
{%- set dep_node = graph.nodes[dep_id] -%}
{%- set rendered_sql = render(dep_node.raw_code) | trim -%}
{%- if rendered_sql -%}
{%- set cte_sql -%}
__dbt__cte__{{ dep_node.name }} AS (
{{ rendered_sql }}
)
{%- endset -%}
{%- do ctes.append(cte_sql) -%}
{%- endif -%}
{%- endfor -%}
{{ log("Number of CTEs generated: " ~ ctes | length, info=True) }}
{# Combine CTEs with main query #}
{%- set final_sql -%}
WITH {{ ctes | join(',\n\n') }}
{{ render(target_node.raw_code) }}
{%- endset -%}
{{ log("=== End get_rendered_model ===\n\n" , info=True) }}
{{ return(final_sql) }}
{% endif %}
{% endmacro %}

View File

@ -5,6 +5,7 @@ models:
- name: udf_json_rpc_call
tests:
- test_udf:
name: test__utils_udf_json_rpc_call
args: "'foo', [], 1"
assertions:
- >
@ -17,182 +18,182 @@ models:
- name: udf_urlencode
tests:
- test_udf:
name: test_utils__udf_urlencode_dict_true_1
name: test__utils_udf_urlencode_dict_true_1
args: >
{'a':'b'}, TRUE
assertions:
- result = 'a=b'
- test_udf:
name: test_utils__udf_urlencode_dict_true_2
name: test__utils_udf_urlencode_dict_true_2
args: >
{'a':'a', 'b':'b'}, TRUE
assertions:
- result = 'a=a&b=b'
- test_udf:
name: test_utils__udf_urlencode_dict_true_space
name: test__utils_udf_urlencode_dict_true_space
args: >
{'space': 'abc 123'}, TRUE
assertions:
- result = 'space=abc+123'
- test_udf:
name: test_utils__udf_urlencode_dict_true_special
name: test__utils_udf_urlencode_dict_true_special
args: >
{'special!': ' !@#$,+"'}, TRUE
assertions:
- result = 'special%21=+%21%40%23%24%2C%2B%22'
- test_udf:
name: test_utils__udf_urlencode_dict_true_array
name: test__utils_udf_urlencode_dict_true_array
args: >
{'array': [0, 1, 2]}, TRUE
assertions:
- result = 'array=0&array=1&array=2'
- test_udf:
name: test_utils__udf_urlencode_dict_false_1
name: test__utils_udf_urlencode_dict_false_1
args: >
{'a':'b'}, FALSE
assertions:
- result = 'a=b'
- test_udf:
name: test_utils__udf_urlencode_dict_false_2
name: test__utils_udf_urlencode_dict_false_2
args: >
{'a':'b', 'b':'b'}, FALSE
assertions:
- result = 'a=b&b=b'
- test_udf:
name: test_utils__udf_urlencode_dict_false_space
name: test__utils_udf_urlencode_dict_false_space
args: >
{'space': 'abc 123'}, FALSE
assertions:
- result = 'space=abc+123'
- test_udf:
name: test_utils__udf_urlencode_dict_false_special
name: test__utils_udf_urlencode_dict_false_special
args: >
{'special!': ' !@#$,+"'}, FALSE
assertions:
- result = 'special%21=+%21%40%23%24%2C%2B%22'
- test_udf:
name: test_utils__udf_urlencode_dict_false_array
name: test__utils_udf_urlencode_dict_false_array
args: >
{'array': [0, 1, 2]}, FALSE
assertions:
- result = 'array=%5B0%2C+1%2C+2%5D'
- test_udf:
name: test_utils__udf_urlencode_dict_1
name: test__utils_udf_urlencode_dict_1
args: >
{'a':'b'}
assertions:
- result = 'a=b'
- test_udf:
name: test_utils__udf_urlencode_dict_2
name: test__utils_udf_urlencode_dict_2
args: >
{'a':'b', 'b':'b'}
assertions:
- result = 'a=b&b=b'
- test_udf:
name: test_utils__udf_urlencode_dict_space
name: test__utils_udf_urlencode_dict_space
args: >
{'space': 'abc 123'}
assertions:
- result = 'space=abc+123'
- test_udf:
name: test_utils__udf_urlencode_dict_special
name: test__utils_udf_urlencode_dict_special
args: >
{'special!': ' !@#$,+"'}
assertions:
- result = 'special%21=+%21%40%23%24%2C%2B%22'
- test_udf:
name: test_utils__udf_urlencode_dict_array
name: test__utils_udf_urlencode_dict_array
args: >
{'array': [0, 1, 2]}
assertions:
- result = 'array=%5B0%2C+1%2C+2%5D'
# write tests but use arrays of arrays instead of dictionaries
- test_udf:
name: test_utils__udf_urlencode_array_true_1
name: test__utils_udf_urlencode_array_true_1
args: >
[['a', 'b']], TRUE
assertions:
- result = 'a=b'
- test_udf:
name: test_utils__udf_urlencode_array_true_2
name: test__utils_udf_urlencode_array_true_2
args: >
[['a', 'a'], ['b', 'b']], TRUE
assertions:
- result = 'a=a&b=b'
- test_udf:
name: test_utils__udf_urlencode_array_true_space
name: test__utils_udf_urlencode_array_true_space
args: >
[['space', 'abc 123']], TRUE
assertions:
- result = 'space=abc+123'
- test_udf:
name: test_utils__udf_urlencode_array_true_special
name: test__utils_udf_urlencode_array_true_special
args: >
[['special!', ' !@#$,+"']], TRUE
assertions:
- result = 'special%21=+%21%40%23%24%2C%2B%22'
- test_udf:
name: test_utils__udf_urlencode_array_true_array
name: test__utils_udf_urlencode_array_true_array
args: >
[['array', [0, 1, 2]]], TRUE
assertions:
- result = 'array=0&array=1&array=2'
- test_udf:
name: test_utils__udf_urlencode_array_false_1
name: test__utils_udf_urlencode_array_false_1
args: >
[['a', 'b']], FALSE
assertions:
- result = 'a=b'
- test_udf:
name: test_utils__udf_urlencode_array_false_2
name: test__utils_udf_urlencode_array_false_2
args: >
[['a', 'a'], ['b', 'b']], FALSE
assertions:
- result = 'a=a&b=b'
- test_udf:
name: test_utils__udf_urlencode_array_false_space
name: test__utils_udf_urlencode_array_false_space
args: >
[['space', 'abc 123']], FALSE
assertions:
- result = 'space=abc+123'
- test_udf:
name: test_utils__udf_urlencode_array_false_special
name: test__utils_udf_urlencode_array_false_special
args: >
[['special!', ' !@#$,+"']], FALSE
assertions:
- result = 'special%21=+%21%40%23%24%2C%2B%22'
- test_udf:
name: test_utils__udf_urlencode_array_false_array
name: test__utils_udf_urlencode_array_false_array
args: >
[['array', [0, 1, 2]]], FALSE
assertions:
- result = 'array=%5B0%2C+1%2C+2%5D'
- test_udf:
name: test_utils__udf_urlencode_array_1
name: test__utils_udf_urlencode_array_1
args: >
[['a', 'b']]
assertions:
- result = 'a=b'
- test_udf:
name: test_utils__udf_urlencode_array_2
name: test__utils_udf_urlencode_array_2
args: >
[['a', 'a'], ['b', 'b']]
assertions:
- result = 'a=a&b=b'
- test_udf:
name: test_utils__udf_urlencode_array_space
name: test__utils_udf_urlencode_array_space
args: >
[['space', 'abc 123']]
assertions:
- result = 'space=abc+123'
- test_udf:
name: test_utils__udf_urlencode_array_special
name: test__utils_udf_urlencode_array_special
args: >
[['special!', ' !@#$,+"']]
assertions:
- result = 'special%21=+%21%40%23%24%2C%2B%22'
- test_udf:
name: test_utils__udf_urlencode_array_array
name: test__utils_udf_urlencode_array_array
args: >
[['array', [0, 1, 2]]]
assertions:
@ -200,35 +201,35 @@ models:
- name: udf_int_to_binary
tests:
- test_udf:
name: test_utils__udf_int_to_binary
name: test__utils_udf_int_to_binary
args: 123456789
assertions:
- result = '111010110111100110100010101'
- name: udf_int_to_binary
tests:
- test_udf:
name: test_utils__udf_int_to_binary_large_number
name: test__utils_udf_int_to_binary_large_number
args: "'123456789123456789123456789123456789123456789'"
assertions:
- result = '101100010010011011011100101001111010001001110011010111111101111101010111011001001101000001111110001010100001011011010000100000001000101111100010101'
- name: udf_binary_to_int
tests:
- test_udf:
name: test_utils__udf_binary_to_int
name: test__utils_udf_binary_to_int
args: '111010110111100110100010101'
assertions:
- result = '123456789'
- name: udf_binary_to_int
tests:
- test_udf:
name: test_utils__udf_binary_to_int_large_number
name: test__utils_udf_binary_to_int_large_number
args: "'110110110100110110100101110101100110100000101111100010101'"
assertions:
- result = '123456789123456789'
- name: udf_evm_decode_log
tests:
- test_udf:
name: test_utils__udf_evm_decode_log
name: test__utils_udf_evm_decode_log
args: >
{
'anonymous': false,

View File

@ -1,9 +0,0 @@
selectors:
- name: test_udfs
definition:
union:
- method: package
value: livequery_models
- exclude:
- livequery_models.deploy.marketplace.quicknode.test_quicknode_solana*
- livequery_models.deploy.marketplace.quicknode.test_quicknode_polygon*

View File

@ -1,12 +1,39 @@
{% test test_udf(model, column_name, args, assertions) %}
{#
This is a generic test for UDFs.
The udfs are deployed using ephemeral models, so we need to
use the ephemeral model name to get the udf name.
The udfs are deployed using ephemeral models, as of dbt-core > 1.8
we need to use `this.identifier` to extract the schema from for base_test_udf().
#}
{%- set schema = model | replace("__dbt__cte__", "") -%}
{%- set schema = schema.split("__") | first -%}
{%- set udf = schema ~ "." ~ column_name -%}
{% set schema = none %}
{% if execute %}
{# Extract schema based on standard pattern `test__<schema_name>_<test_name> #}
{% set test_identifier = this.identifier %}
{% if test_identifier.startswith('test_') %}
{% set test_identifier = test_identifier[5:] %}
{% endif %}
{# Handle schemas with underscore prefix #}
{% if test_identifier.startswith('_') %}
{# For identifiers like _utils_<test_name> #}
{% set parts = test_identifier.split('_') %}
{% if parts | length > 2 %}
{% set schema = '_' ~ parts[1] %}
{% else %}
{% set schema = parts[0] %}
{% endif %}
{% else %}
{# For identifiers without underscore prefix #}
{% set parts = test_identifier.split('_') %}
{% if parts | length > 0 %}
{% set schema = parts[0] %}
{% endif %}
{% endif %}
{% endif %}
{% set udf = schema ~ "." ~ column_name %}
{{ base_test_udf(model, udf, args, assertions) }}
{% endtest %}