diff --git a/.gitattributes b/.gitattributes
index abd1d5471..2cda5ad55 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,17 +1,18 @@
+.github export-ignore
+.idea export-ignore
+development export-ignore
+test export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.gitmodules export-ignore
-.travis.yml export-ignore
mkdocs.yml export-ignore
-.travis export-ignore
-.github export-ignore
+BUILD_NO export-ignore
+mkdocs_offline.yml export-ignore
sonar-project.properties export-ignore
-tests export-ignore
-development export-ignore
-node_modules export-ignore
-^docs/* linguist-documentation
+^docs/** linguist-documentation
*.pkb linguist-language=PLSQL
*.pks linguist-language=PLSQL
*.sql linguist-language=PLSQL
*.tpb linguist-language=PLSQL
*.tps linguist-language=PLSQL
+*.sh text eol=lf
diff --git a/.github/DISCUSSION_TEMPLATE/bug-triage.yml b/.github/DISCUSSION_TEMPLATE/bug-triage.yml
new file mode 100644
index 000000000..7a5da8d73
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/bug-triage.yml
@@ -0,0 +1,69 @@
+title: "[Bug?] "
+labels: ["bug-triage"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Use this category if you think you have found a bug in the utPLSQL framework and want to discuss it before a formal issue is opened.
+
+ Once a maintainer confirms the bug, they will open an issue and link it back here. You do not need to open an issue yourself.
+
+ If you are certain it is a bug and can provide a reliable reproduction, you may open an issue directly instead.
+
+ - type: input
+ id: utplsql-version
+ attributes:
+ label: utPLSQL version
+ placeholder: "e.g. 3.1.13"
+ validations:
+ required: true
+
+ - type: input
+ id: oracle-version
+ attributes:
+ label: Oracle Database version
+ placeholder: "e.g. 19c, 21c"
+ validations:
+ required: true
+
+ - type: input
+ id: os
+ attributes:
+ label: Operating system
+ placeholder: "e.g. Linux, Windows Server 2019"
+ validations:
+ required: false
+
+ - type: textarea
+ id: description
+ attributes:
+ label: What did you observe?
+ description: Describe the unexpected behaviour. Include any error messages or stack traces.
+ render: text
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: What did you expect?
+ description: Describe what you expected to happen instead.
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproduction
+ attributes:
+ label: Reproduction case
+ description: Paste the minimal PL/SQL needed to reproduce the problem. The simpler, the better.
+ render: sql
+ validations:
+ required: false
+
+ - type: textarea
+ id: investigation
+ attributes:
+ label: What have you investigated so far?
+ description: Any findings from your own debugging that might help narrow this down.
+ validations:
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/contributing.yml b/.github/DISCUSSION_TEMPLATE/contributing.yml
new file mode 100644
index 000000000..31a213cbb
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/contributing.yml
@@ -0,0 +1,43 @@
+title: ""
+labels: ["contributing"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Use this category if you are working on or considering a contribution to the utPLSQL framework codebase and have questions about the internals, development setup, testing approach, or contribution process.
+
+ Before posting, it is worth checking:
+ - [CONTRIBUTING.md](https://github.com/utPLSQL/utPLSQL/blob/develop/CONTRIBUTING.md)
+ - [Development setup guide](https://github.com/utPLSQL/utPLSQL/blob/develop/development/README.md)
+
+ - type: dropdown
+ id: topic
+ attributes:
+ label: Topic
+ options:
+ - Development environment setup
+ - Understanding the codebase
+ - Test writing and running locally
+ - CI / build pipeline
+ - Pull request process
+ - Architectural question
+ - Other
+ validations:
+ required: true
+
+ - type: textarea
+ id: question
+ attributes:
+ label: Question or topic
+ description: Describe what you are working on and what you need help with.
+ validations:
+ required: true
+
+ - type: textarea
+ id: context
+ attributes:
+ label: Relevant code or context
+ description: Paste any relevant code, configuration, or error output here.
+ render: sql
+ validations:
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/feature-requests.yml b/.github/DISCUSSION_TEMPLATE/feature-requests.yml
new file mode 100644
index 000000000..b07a043b5
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/feature-requests.yml
@@ -0,0 +1,61 @@
+title: "[Feature] "
+labels: ["feature-request"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Use this category for feature ideas specific to the utPLSQL framework: new matchers, annotation behaviour, reporter output, suite control, coverage, or installation.
+
+ > For ideas that affect multiple components or the project direction overall, use [org-level Feature Requests](https://github.com/orgs/utPLSQL/discussions/categories/feature-requests) instead.
+
+ A maintainer will mark this discussion as answered once the proposal is accepted or declined.
+ If accepted, a maintainer will convert it to an issue for implementation tracking -- you do not need to open an issue yourself.
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem or motivation
+ description: What problem does this feature solve? What is the current limitation or pain point?
+ validations:
+ required: true
+
+ - type: textarea
+ id: proposal
+ attributes:
+ label: Proposed solution
+ description: Describe the feature you have in mind. Include examples of how it would be used, ideally with PL/SQL annotation or API examples.
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives or workarounds considered
+ description: Have you found any alternative approaches or partial workarounds?
+ validations:
+ required: false
+
+ - type: dropdown
+ id: area
+ attributes:
+ label: Framework area
+ options:
+ - Annotations
+ - Matchers
+ - Reporters
+ - Suite / test control
+ - Coverage
+ - Transaction control
+ - Installation / upgrade
+ - Performance
+ - Other
+ validations:
+ required: true
+
+ - type: input
+ id: utplsql-version
+ attributes:
+ label: utPLSQL version you are using
+ placeholder: "e.g. 3.1.13"
+ validations:
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/q-a.yml b/.github/DISCUSSION_TEMPLATE/q-a.yml
new file mode 100644
index 000000000..30b372760
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/q-a.yml
@@ -0,0 +1,61 @@
+title: "[Q&A] "
+labels: ["question"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## Question & Answer
+ Ask anything about **using** utPLSQL — installation, writing tests, CI integration,
+ reporters, annotations, code coverage, etc.
+
+ **Tips for a fast answer:**
+ - Include your utPLSQL version and Oracle version.
+ - Paste a minimal reproducer (test package + expected vs actual output).
+ - Check the [documentation](https://utplsql.github.io/utPLSQL/) and
+ [closed Q&A discussions](../../discussions/categories/q-a?discussions_q=is%3Aclosed) first.
+
+ > If this turns out to be a **bug**, a maintainer will convert this discussion into an Issue.
+
+ - type: input
+ id: utplsql-version
+ attributes:
+ label: utPLSQL version
+ placeholder: "e.g. 3.1.13"
+ validations:
+ required: true
+
+ - type: input
+ id: oracle-version
+ attributes:
+ label: Oracle Database version
+ placeholder: "e.g. 19c, 21c"
+ validations:
+ required: true
+
+ - type: textarea
+ id: question
+ attributes:
+ label: Question
+ description: Describe what you are trying to do and what you have already tried.
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproducer
+ attributes:
+ label: Minimal reproducer
+ description: |
+ Paste a minimal test package and/or the relevant ut_runner call.
+ Include the full error message or unexpected output if applicable.
+ render: sql
+ validations:
+ required: false
+
+ - type: textarea
+ id: output
+ attributes:
+ label: Actual output or error
+ description: Paste any error messages or unexpected output here.
+ render: text
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 681bc7f3a..f0335781e 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -23,4 +23,4 @@ Add any other context or screenshots about the feature request here.
> Please do not create issues for generic SQL or PL/SQL questions. There are other forums and communities to help you with those. See [ASKTom](https://asktom.oracle.com) for example.
**Want to discuss**
-If you want to discuss your issue, join [our SLACK chat](https://join.slack.com/t/utplsql/shared_invite/zt-xwm68udy-4cF_3PNEyczYEbWr38W5ww).
+If you want to discuss a problem, please go to [utPLSQL discussions](https://github.com/utPLSQL/utPLSQL/discussions)
diff --git a/.github/scripts/create_test_users.sh b/.github/scripts/create_test_users.sh
index fe43b7467..6c3030206 100755
--- a/.github/scripts/create_test_users.sh
+++ b/.github/scripts/create_test_users.sh
@@ -18,6 +18,9 @@ PROMPT Creating UT3_TESTER - Power-user for testing internal framework code
create user UT3_TESTER identified by "ut3" default tablespace $UT3_TABLESPACE quota unlimited on $UT3_TABLESPACE;
grant create session, create procedure, create type, create table to UT3_TESTER;
+# Editioning is enable on test users to validate that utPLSQL works well with editioned schema
+alter user UT3_TESTER enable editions;
+
grant execute on dbms_lock to UT3_TESTER;
PROMPT Granting $UT3_DEVELOP_SCHEMA code to UT3_TESTER
@@ -52,6 +55,9 @@ PROMPT Creating UT3_USER - minimal privileges user for API testing
create user UT3_USER identified by "ut3" default tablespace $UT3_TABLESPACE quota unlimited on $UT3_TABLESPACE;
grant create session, create procedure, create type, create table to UT3_USER;
+# Editioning is enable on test users to validate that utPLSQL works well with editioned schema
+alter user UT3_USER enable editions;
+
PROMPT Grants for starting a debugging session from UT3_USER
grant debug connect session to UT3_USER;
grant debug any procedure to UT3_USER;
@@ -86,7 +92,7 @@ PROMPT Grants for testing coverage outside of main $UT3_DEVELOP_SCHEMA schema.
grant create any procedure, drop any procedure, execute any procedure, create any type, drop any type, execute any type, under any type,
select any table, update any table, insert any table, delete any table, create any table, drop any table, alter any table,
select any dictionary, create any synonym, drop any synonym,
- grant any object privilege, grant any privilege, create public synonym, drop public synonym, create any trigger
+ grant any object privilege, grant any privilege, create public synonym, drop public synonym, create any trigger, drop any trigger
to UT3_TESTER_HELPER;
grant create job to UT3_TESTER_HELPER;
diff --git a/.github/scripts/get_project_build_version.sh b/.github/scripts/get_project_build_version.sh
deleted file mode 100755
index 838523b05..000000000
--- a/.github/scripts/get_project_build_version.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/usr/bin/env bash
-echo `sed -E "s/(v?[0-9]+\.)([0-9]+\.)([0-9]+)(-.*)?/\1\2\3\.${UTPLSQL_BUILD_NO}\4/" <<< "${UTPLSQL_VERSION}"`
diff --git a/.github/scripts/get_project_version.sh b/.github/scripts/get_project_version.sh
index 60fc0a796..54a30a562 100755
--- a/.github/scripts/get_project_version.sh
+++ b/.github/scripts/get_project_version.sh
@@ -1,14 +1,7 @@
#!/usr/bin/env bash
-
-#When building a new version from a release branch, the version is taken from release branch name
-if [[ "${CI_ACTION_REF_NAME}" =~ ^release/v[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
- version=${CI_ACTION_REF_NAME#release\/}
-else
- #Otherwise, version is taken from the VERSION file
- version=`cat VERSION`
- #When on develop branch, add "-develop" to the version text
- if [[ "${CI_ACTION_REF_NAME}" == "develop" ]]; then
+version=`cat VERSION`
+#When on develop branch, add "-develop" to the version text
+if [[ "${CI_ACTION_REF_NAME}" == "develop" ]]; then
version=`sed -E "s/(v?[0-9]+\.[0-9]+\.[0-9]+).*/\1-develop/" <<< "${version}"`
- fi
fi
echo ${version}
diff --git a/.github/scripts/install.sh b/.github/scripts/install.sh
index 46750b89c..5f034951c 100755
--- a/.github/scripts/install.sh
+++ b/.github/scripts/install.sh
@@ -19,3 +19,13 @@ set verify off
alter session set plsql_optimize_level=0;
@${INSTALL_FILE} $UT3_DEVELOP_SCHEMA $UT3_DEVELOP_SCHEMA_PASSWORD
SQL
+
+#Enable editioning on the UT3_DEVELOP schema
+time "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL
+whenever sqlerror exit failure rollback
+set feedback off
+set verify off
+
+alter user $UT3_DEVELOP_SCHEMA enable editions;
+exit
+SQL
diff --git a/.github/scripts/post_release_announcement.sh b/.github/scripts/post_release_announcement.sh
new file mode 100755
index 000000000..c74394505
--- /dev/null
+++ b/.github/scripts/post_release_announcement.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# Posts a release announcement to the utPLSQL org .github repository's
+# Announcements discussion category.
+#
+# Required environment variables:
+# GH_TOKEN - GitHub token with write:discussion scope (ORG_DISCUSSION_TOKEN)
+# RELEASE_TAG - e.g. v3.2.3
+# RELEASE_BODY - markdown release notes
+# RELEASE_URL - URL of the GitHub release page
+
+set -euo pipefail
+
+ORG="utPLSQL"
+REPO_NAME=".github"
+
+# Get org node ID
+ORG_DATA=$(gh api graphql -f query='query($org: String!) {
+ organization(login: $org) {
+ id
+ }
+}' -f org="$ORG")
+ORG_ID=$(echo "$ORG_DATA" | jq -r '.data.organization.id')
+
+# Get repository node ID
+REPO_DATA=$(gh api graphql -f query='query($owner: String!, $name: String!) {
+ repository(owner: $owner, name: $name) {
+ id
+ }
+}' -f owner="$ORG" -f name="$REPO_NAME")
+REPO_ID=$(echo "$REPO_DATA" | jq -r '.data.repository.id')
+
+# Get Announcements category ID
+CATEGORY_DATA=$(gh api graphql -f query='query($owner: String!, $name: String!) {
+ repository(owner: $owner, name: $name) {
+ discussionCategories(first: 20) {
+ nodes { id name }
+ }
+ }
+}' -f owner="$ORG" -f name="$REPO_NAME")
+CATEGORY_ID=$(echo "$CATEGORY_DATA" | jq -r \
+ '.data.repository.discussionCategories.nodes[] | select(.name == "Announcements") | .id')
+
+BODY="${RELEASE_BODY}
+
+
utPLSQL has been supported by Redgate in the form of sponsored stickers and t-shirts. Thank you for helping us spreading the word!
-
-
-
+The list of **authors** and **significant contributors** is available on the [About](https://www.utplsql.org/about/) page. For a full list of contributors, see [contributors](https://github.com/utPLSQL/utPLSQL/graphs/contributors?all=1) on GitHub.
diff --git a/sonar-project.properties b/sonar-project.properties
index 5d6cefe12..0a835a2f3 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -1,9 +1,9 @@
# must be unique in a given SonarQube instance
sonar.organization=utplsql
-sonar.projectKey=utPLSQL
+sonar.projectKey=utPLSQL_utPLSQL
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=utPLSQL
-sonar.projectVersion=v3.1.13-develop
+sonar.projectVersion=v3.2.4-develop
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# Since SonarQube 4.2, this property is optional if sonar.modules is set.
@@ -15,7 +15,7 @@ sonar.coverage.exclusions=**/*.sql,**/*.pks
sonar.tests=./test
sonar.testExecutionReportPaths=./test_results.xml
sonar.links.issue=https://github.com/utPLSQL/utPLSQL/issues
-sonar.links.ci=https://travis-ci.org/utPLSQL/utPLSQL
+sonar.links.ci=https://github.com/utPLSQL/utPLSQL/actions
sonar.links.homepage=https://github.com/utPLSQL/utPLSQL
sonar.projectDescription=PL/SQL Unit Testing Framework
sonar.plsql.file.suffixes=sql,tab,pkb,tpb
diff --git a/source/api/be_between.syn b/source/api/be_between.syn
index c0972595d..233dd65bf 100644
--- a/source/api/be_between.syn
+++ b/source/api/be_between.syn
@@ -1 +1 @@
-create synonym be_between for ut_be_between;
+create noneditionable synonym be_between for ut_be_between;
diff --git a/source/api/be_empty.syn b/source/api/be_empty.syn
index a8e28de6e..f63366fa3 100644
--- a/source/api/be_empty.syn
+++ b/source/api/be_empty.syn
@@ -1 +1 @@
-create synonym be_empty for ut_be_empty;
+create noneditionable synonym be_empty for ut_be_empty;
diff --git a/source/api/be_false.syn b/source/api/be_false.syn
index c2665bbcb..cdf497235 100644
--- a/source/api/be_false.syn
+++ b/source/api/be_false.syn
@@ -1 +1 @@
-create synonym be_false for ut_be_false;
+create noneditionable synonym be_false for ut_be_false;
diff --git a/source/api/be_greater_or_equal.syn b/source/api/be_greater_or_equal.syn
index 386fe7f32..67616dc1d 100644
--- a/source/api/be_greater_or_equal.syn
+++ b/source/api/be_greater_or_equal.syn
@@ -1 +1 @@
-create synonym be_greater_or_equal for ut_be_greater_or_equal;
+create noneditionable synonym be_greater_or_equal for ut_be_greater_or_equal;
diff --git a/source/api/be_greater_than.syn b/source/api/be_greater_than.syn
index 6f97b7d22..c180f3d43 100644
--- a/source/api/be_greater_than.syn
+++ b/source/api/be_greater_than.syn
@@ -1 +1 @@
-create synonym be_greater_than for ut_be_greater_than;
+create noneditionable synonym be_greater_than for ut_be_greater_than;
diff --git a/source/api/be_less_or_equal.syn b/source/api/be_less_or_equal.syn
index b2f836144..0069f52ba 100644
--- a/source/api/be_less_or_equal.syn
+++ b/source/api/be_less_or_equal.syn
@@ -1 +1 @@
-create synonym be_less_or_equal for ut_be_less_or_equal;
+create noneditionable synonym be_less_or_equal for ut_be_less_or_equal;
diff --git a/source/api/be_less_than.syn b/source/api/be_less_than.syn
index fbef3b4c3..5d2766d05 100644
--- a/source/api/be_less_than.syn
+++ b/source/api/be_less_than.syn
@@ -1 +1 @@
-create synonym be_less_than for ut_be_less_than;
+create noneditionable synonym be_less_than for ut_be_less_than;
diff --git a/source/api/be_like.syn b/source/api/be_like.syn
index a8be1de71..6f62f21a0 100644
--- a/source/api/be_like.syn
+++ b/source/api/be_like.syn
@@ -1 +1 @@
-create synonym be_like for ut_be_like;
+create noneditionable synonym be_like for ut_be_like;
diff --git a/source/api/be_not_null.syn b/source/api/be_not_null.syn
index d6458683a..a9e02b94d 100644
--- a/source/api/be_not_null.syn
+++ b/source/api/be_not_null.syn
@@ -1 +1 @@
-create synonym be_not_null for ut_be_not_null;
+create noneditionable synonym be_not_null for ut_be_not_null;
diff --git a/source/api/be_null.syn b/source/api/be_null.syn
index 42f6516c3..4fe3fb9dd 100644
--- a/source/api/be_null.syn
+++ b/source/api/be_null.syn
@@ -1 +1 @@
-create synonym be_null for ut_be_null;
+create noneditionable synonym be_null for ut_be_null;
diff --git a/source/api/be_true.syn b/source/api/be_true.syn
index bf7392a62..1aa348c7e 100644
--- a/source/api/be_true.syn
+++ b/source/api/be_true.syn
@@ -1 +1 @@
-create synonym be_true for ut_be_true;
+create noneditionable synonym be_true for ut_be_true;
diff --git a/source/api/be_within.syn b/source/api/be_within.syn
index e00005bb7..4f4f77606 100644
--- a/source/api/be_within.syn
+++ b/source/api/be_within.syn
@@ -1 +1 @@
-create synonym be_within for ut_be_within;
+create noneditionable synonym be_within for ut_be_within;
diff --git a/source/api/be_within_pct.syn b/source/api/be_within_pct.syn
index 40e3fb8b9..b9fc1cd53 100644
--- a/source/api/be_within_pct.syn
+++ b/source/api/be_within_pct.syn
@@ -1 +1 @@
-create synonym be_within_pct for ut_be_within_pct;
+create noneditionable synonym be_within_pct for ut_be_within_pct;
diff --git a/source/api/contain.syn b/source/api/contain.syn
index 5bce7d1d2..5b4158635 100644
--- a/source/api/contain.syn
+++ b/source/api/contain.syn
@@ -1 +1 @@
-create synonym contain for ut_contain;
+create noneditionable synonym contain for ut_contain;
diff --git a/source/api/equal.syn b/source/api/equal.syn
index 71ba58b53..0d81fcf6f 100644
--- a/source/api/equal.syn
+++ b/source/api/equal.syn
@@ -1 +1 @@
-create synonym equal for ut_equal;
+create noneditionable synonym equal for ut_equal;
diff --git a/source/api/have_count.syn b/source/api/have_count.syn
index a406d47ec..9cbf8ebf2 100644
--- a/source/api/have_count.syn
+++ b/source/api/have_count.syn
@@ -1 +1 @@
-create synonym have_count for ut_have_count;
+create noneditionable synonym have_count for ut_have_count;
diff --git a/source/api/match.syn b/source/api/match.syn
index ffbda35b1..13e8cc97d 100644
--- a/source/api/match.syn
+++ b/source/api/match.syn
@@ -1 +1 @@
-create synonym match for ut_match;
+create noneditionable synonym match for ut_match;
diff --git a/source/api/ut.pkb b/source/api/ut.pkb
index 5c91e54d4..0a847cfaa 100644
--- a/source/api/ut.pkb
+++ b/source/api/ut.pkb
@@ -1,8 +1,8 @@
-create or replace package body ut is
+create or replace noneditionable package body ut is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -222,10 +222,15 @@ create or replace package body ut is
raise_if_packages_invalidated();
raise no_data_found;
end if;
- g_result_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len);
- g_result_line_no := g_result_lines.first;
+ if l_clob is not null and l_clob != empty_clob() then
+ if length(l_clob) > ut_utils.gc_max_storage_varchar2_len then
+ g_result_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len);
+ else
+ g_result_lines := ut_varchar2_list(l_clob);
+ end if;
+ g_result_line_no := g_result_lines.first;
+ end if;
end if;
-
if g_result_line_no is not null then
l_result := g_result_lines(g_result_line_no);
g_result_line_no := g_result_lines.next(g_result_line_no);
@@ -273,6 +278,7 @@ create or replace package body ut is
);
if l_reporter is of (ut_output_reporter_base) then
l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor();
+ g_result_lines := ut_varchar2_list();
loop
pipe row( get_report_outputs( l_results ) );
end loop;
@@ -320,6 +326,7 @@ create or replace package body ut is
);
if l_reporter is of (ut_output_reporter_base) then
l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor();
+ g_result_lines := ut_varchar2_list();
loop
pipe row( get_report_outputs( l_results ) );
end loop;
@@ -368,6 +375,7 @@ create or replace package body ut is
);
if l_reporter is of (ut_output_reporter_base) then
l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor();
+ g_result_lines := ut_varchar2_list();
loop
pipe row( get_report_outputs( l_results ) );
end loop;
@@ -416,6 +424,7 @@ create or replace package body ut is
);
if l_reporter is of (ut_output_reporter_base) then
l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor();
+ g_result_lines := ut_varchar2_list();
loop
pipe row( get_report_outputs( l_results ) );
end loop;
@@ -464,6 +473,7 @@ create or replace package body ut is
);
if l_reporter is of (ut_output_reporter_base) then
l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor();
+ g_result_lines := ut_varchar2_list();
loop
pipe row( get_report_outputs( l_results ) );
end loop;
@@ -512,6 +522,7 @@ create or replace package body ut is
);
if l_reporter is of (ut_output_reporter_base) then
l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor();
+ g_result_lines := ut_varchar2_list();
loop
pipe row( get_report_outputs( l_results ) );
end loop;
diff --git a/source/api/ut.pks b/source/api/ut.pks
index f72c82a0c..fdba6b019 100644
--- a/source/api/ut.pks
+++ b/source/api/ut.pks
@@ -1,8 +1,8 @@
-create or replace package ut authid current_user as
+create or replace noneditionable package ut authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb
index b69a51a04..0db1d6e96 100644
--- a/source/api/ut_runner.pkb
+++ b/source/api/ut_runner.pkb
@@ -1,8 +1,8 @@
-create or replace package body ut_runner is
+create or replace noneditionable package body ut_runner is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -78,8 +78,7 @@ create or replace package body ut_runner is
l_run ut_run;
l_coverage_schema_names ut_varchar2_rows;
l_paths ut_varchar2_list;
- l_random_test_order_seed positive;
- l_tags ut_varchar2_rows := ut_varchar2_rows();
+ l_random_test_order_seed positive;
begin
ut_event_manager.initialize();
if a_reporters is not empty then
@@ -118,12 +117,6 @@ create or replace package body ut_runner is
l_coverage_schema_names := ut_suite_manager.get_schema_names(l_paths);
end if;
-
- if a_tags is not null then
- l_tags := l_tags multiset union distinct ut_utils.convert_collection(
- ut_utils.trim_list_elements(ut_utils.filter_list(ut_utils.string_to_table(a_tags,','),ut_utils.gc_word_no_space))
- );
- end if;
l_run := ut_run(
a_run_paths => l_paths,
a_coverage_options => ut_coverage_options(
@@ -140,10 +133,10 @@ create or replace package body ut_runner is
a_test_file_mappings => set(a_test_file_mappings),
a_client_character_set => a_client_character_set,
a_random_test_order_seed => l_random_test_order_seed,
- a_run_tags => l_tags
+ a_run_tags => a_tags
);
- ut_suite_manager.configure_execution_by_path(l_paths, l_run.items, l_random_test_order_seed, l_tags);
+ ut_suite_manager.configure_execution_by_path(l_paths, l_run.items, l_random_test_order_seed, a_tags);
if a_force_manual_rollback then
l_run.set_rollback_type( a_rollback_type => ut_utils.gc_rollback_manual, a_force => true );
end if;
diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks
index 85eff1c93..17bd0fa7a 100644
--- a/source/api/ut_runner.pks
+++ b/source/api/ut_runner.pks
@@ -1,8 +1,8 @@
-create or replace package ut_runner authid current_user is
+create or replace noneditionable package ut_runner authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/api/ut_suite_item_info.tpb b/source/api/ut_suite_item_info.tpb
index 3315f7a16..d18f078ee 100644
--- a/source/api/ut_suite_item_info.tpb
+++ b/source/api/ut_suite_item_info.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_suite_item_info is
+create or replace noneditionable type body ut_suite_item_info is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/api/ut_suite_item_info.tps b/source/api/ut_suite_item_info.tps
index 2c92f261d..4b4f9d52c 100644
--- a/source/api/ut_suite_item_info.tps
+++ b/source/api/ut_suite_item_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_item_info as object (
+create or replace noneditionable type ut_suite_item_info as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/api/ut_suite_items_info.tps b/source/api/ut_suite_items_info.tps
index 208098f9d..5a04c9a74 100644
--- a/source/api/ut_suite_items_info.tps
+++ b/source/api/ut_suite_items_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_items_info as
+create or replace noneditionable type ut_suite_items_info as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/check_object_grants.sql b/source/check_object_grants.sql
index 5f560e6b1..0e7a9b4c9 100644
--- a/source/check_object_grants.sql
+++ b/source/check_object_grants.sql
@@ -1,3 +1,20 @@
+/*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
declare
$if dbms_db_version.version >= 18 $then
c_expected_grants constant dbmsoutput_linesarray := dbmsoutput_linesarray('DBMS_CRYPTO');
diff --git a/source/check_sys_grants.sql b/source/check_sys_grants.sql
index 79b657328..f81157183 100644
--- a/source/check_sys_grants.sql
+++ b/source/check_sys_grants.sql
@@ -1,3 +1,20 @@
+/*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
define expected_grants = "&1"
declare
c_expected_grants constant dbmsoutput_linesarray := dbmsoutput_linesarray( &expected_grants );
diff --git a/source/core/annotations/ut_annotated_object.tps b/source/core/annotations/ut_annotated_object.tps
index 3fda363fe..ca327d7fc 100644
--- a/source/core/annotations/ut_annotated_object.tps
+++ b/source/core/annotations/ut_annotated_object.tps
@@ -1,7 +1,7 @@
-create type ut_annotated_object as object(
+create or replace noneditionable type ut_annotated_object as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotated_objects.tps b/source/core/annotations/ut_annotated_objects.tps
index c67c1bd53..2b338e7d9 100644
--- a/source/core/annotations/ut_annotated_objects.tps
+++ b/source/core/annotations/ut_annotated_objects.tps
@@ -1,7 +1,7 @@
-create type ut_annotated_objects as
+create or replace noneditionable type ut_annotated_objects as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation.tps b/source/core/annotations/ut_annotation.tps
index 3d0311571..cc1f90e86 100644
--- a/source/core/annotations/ut_annotation.tps
+++ b/source/core/annotations/ut_annotation.tps
@@ -1,7 +1,7 @@
-create type ut_annotation as object(
+create or replace noneditionable type ut_annotation as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_cache.sql b/source/core/annotations/ut_annotation_cache.sql
index 67149ce60..7d69b1db6 100644
--- a/source/core/annotations/ut_annotation_cache.sql
+++ b/source/core/annotations/ut_annotation_cache.sql
@@ -1,7 +1,7 @@
create table ut_annotation_cache (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/annotations/ut_annotation_cache_info.sql b/source/core/annotations/ut_annotation_cache_info.sql
index 167973a04..6248f4fbc 100644
--- a/source/core/annotations/ut_annotation_cache_info.sql
+++ b/source/core/annotations/ut_annotation_cache_info.sql
@@ -1,7 +1,7 @@
create table ut_annotation_cache_info (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/annotations/ut_annotation_cache_manager.pkb b/source/core/annotations/ut_annotation_cache_manager.pkb
index e1131b3bd..afc473404 100644
--- a/source/core/annotations/ut_annotation_cache_manager.pkb
+++ b/source/core/annotations/ut_annotation_cache_manager.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_annotation_cache_manager as
+create or replace noneditionable package body ut_annotation_cache_manager as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_cache_manager.pks b/source/core/annotations/ut_annotation_cache_manager.pks
index 1e9734934..1aa4cb501 100644
--- a/source/core/annotations/ut_annotation_cache_manager.pks
+++ b/source/core/annotations/ut_annotation_cache_manager.pks
@@ -1,7 +1,7 @@
-create or replace package ut_annotation_cache_manager authid definer as
+create or replace noneditionable package ut_annotation_cache_manager authid definer as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_cache_schema.sql b/source/core/annotations/ut_annotation_cache_schema.sql
index 8889b9abf..b8ebaa40b 100644
--- a/source/core/annotations/ut_annotation_cache_schema.sql
+++ b/source/core/annotations/ut_annotation_cache_schema.sql
@@ -1,7 +1,7 @@
create table ut_annotation_cache_schema (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/annotations/ut_annotation_cache_seq.sql b/source/core/annotations/ut_annotation_cache_seq.sql
index b371b382b..f0f1f17d7 100644
--- a/source/core/annotations/ut_annotation_cache_seq.sql
+++ b/source/core/annotations/ut_annotation_cache_seq.sql
@@ -1,7 +1,7 @@
create sequence ut_annotation_cache_seq
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/annotations/ut_annotation_manager.pkb b/source/core/annotations/ut_annotation_manager.pkb
index 16923bc23..b35f40075 100644
--- a/source/core/annotations/ut_annotation_manager.pkb
+++ b/source/core/annotations/ut_annotation_manager.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_annotation_manager as
+create or replace noneditionable package body ut_annotation_manager as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -121,6 +121,7 @@ create or replace package body ut_annotation_manager as
and s.type = r.object_type
where s.owner = ']'||ut_utils.qualified_sql_name(a_object_owner)||q'['
and s.type = ']'||ut_utils.qualified_sql_name(a_object_type)||q'['
+ and s.origin_con_id = sys_context('userenv', 'con_id')
) x
where x.is_annotated = 'Y'
order by x.name, x.line]'
@@ -143,34 +144,37 @@ create or replace package body ut_annotation_manager as
l_parse_time date := sysdate;
pragma autonomous_transaction;
begin
- loop
- fetch a_sources_cursor bulk collect into l_names, l_lines limit c_lines_fetch_limit;
- for i in 1 .. l_names.count loop
- if l_names(i) != l_name then
- l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines, a_object_type);
- ut_annotation_cache_manager.update_cache(
- ut_annotated_object(a_object_owner, l_name, a_object_type, l_parse_time, l_annotations)
- );
- l_object_lines.delete;
- end if;
-
- l_name := l_names(i);
- l_object_lines(l_object_lines.count+1) := l_lines(i);
- end loop;
- exit when a_sources_cursor%notfound;
+ begin
+ loop
+ fetch a_sources_cursor bulk collect into l_names, l_lines limit c_lines_fetch_limit;
+ for i in 1 .. l_names.count loop
+ if l_names(i) != l_name then
+ l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines, a_object_type);
+ ut_annotation_cache_manager.update_cache(
+ ut_annotated_object(a_object_owner, l_name, a_object_type, l_parse_time, l_annotations)
+ );
+ l_object_lines.delete;
+ end if;
+
+ l_name := l_names(i);
+ l_object_lines(l_object_lines.count+1) := l_lines(i);
+ end loop;
+ exit when a_sources_cursor%notfound;
- end loop;
- if a_sources_cursor%rowcount > 0 then
- l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines, a_object_type);
- ut_annotation_cache_manager.update_cache(
- ut_annotated_object(a_object_owner, l_name, a_object_type, l_parse_time, l_annotations)
- );
- l_object_lines.delete;
+ end loop;
+ if a_sources_cursor%rowcount > 0 then
+ l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines, a_object_type);
+ ut_annotation_cache_manager.update_cache(
+ ut_annotated_object(a_object_owner, l_name, a_object_type, l_parse_time, l_annotations)
+ );
+ l_object_lines.delete;
+ end if;
+ end;
+ if a_sources_cursor%isopen then
+ close a_sources_cursor;
end if;
- close a_sources_cursor;
end;
-
procedure validate_annotation_cache(
a_object_owner varchar2,
a_object_type varchar2,
@@ -231,23 +235,24 @@ create or replace package body ut_annotation_manager as
function get_source_from_sql_text(a_object_name varchar2, a_sql_text ora_name_list_t, a_parts binary_integer) return sys_refcursor is
l_sql_clob clob;
- l_sql_lines ut_varchar2_rows := ut_varchar2_rows();
+ l_sql_lines dbms_preprocessor.source_lines_t := dbms_preprocessor.source_lines_t();
+ l_sql_lines_clob ut_varchar2_list := ut_varchar2_list();
l_result sys_refcursor;
begin
if a_parts > 0 then
for i in 1..a_parts loop
ut_utils.append_to_clob(l_sql_clob, a_sql_text(i));
end loop;
- l_sql_clob := ut_utils.replace_multiline_comments(l_sql_clob);
- -- replace comment lines that contain "-- create or replace"
- l_sql_clob := regexp_replace(l_sql_clob, '^.*[-]{2,}\s*create(\s+or\s+replace).*$', modifier => 'mi');
- -- remove the "create [or replace] [[non]editionable] " so that we have only "type|package" for parsing
- -- needed for dbms_preprocessor
- l_sql_clob := regexp_replace(l_sql_clob, '^(.*?\s*create(\s+or\s+replace)?(\s+(editionable|noneditionable))?\s+?)((package|type).*)', '\5', 1, 1, 'ni');
- -- remove "OWNER." from create or replace statement.
- -- Owner is not supported along with AUTHID - see issue https://github.com/utPLSQL/utPLSQL/issues/1088
- l_sql_clob := regexp_replace(l_sql_clob, '^(package|type)\s+("?[a-zA-Z][a-zA-Z0-9#_$]*"?\.)(.*)', '\1 \3', 1, 1, 'ni');
- l_sql_lines := ut_utils.convert_collection( ut_utils.clob_to_table(l_sql_clob) );
+
+ l_sql_lines_clob := ut_utils.clob_to_table(l_sql_clob);
+ for i in 1..l_sql_lines_clob.count loop
+ l_sql_lines(i) := l_sql_lines_clob(i);
+ end loop;
+
+ -- replace multiline comments that contain "-- create or replace" with single line comment to avoid parsing issues with dbms_preprocessor
+ l_sql_lines := ut_utils.replace_multiline_comments(l_sql_lines);
+ -- strip CREATE header (possibly split across lines) while preserving line numbers
+ l_sql_lines := ut_utils.strip_create_header_lines(l_sql_lines);
end if;
open l_result for
select /*+ no_parallel */ a_object_name as name, column_value||chr(10) as text from table(l_sql_lines);
@@ -264,6 +269,7 @@ create or replace package body ut_annotation_manager as
where s.type = :a_object_type
and s.owner = :a_object_owner
and s.name = :a_object_name
+ and s.origin_con_id = sys_context('userenv', 'con_id')
order by s.line]'
using a_object_name, a_object_type, a_object_owner, a_object_name;
return l_result;
diff --git a/source/core/annotations/ut_annotation_manager.pks b/source/core/annotations/ut_annotation_manager.pks
index 20fcd810f..eedef002a 100644
--- a/source/core/annotations/ut_annotation_manager.pks
+++ b/source/core/annotations/ut_annotation_manager.pks
@@ -1,7 +1,7 @@
-create or replace package ut_annotation_manager authid current_user as
+create or replace noneditionable package ut_annotation_manager authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_obj_cache_info.tps b/source/core/annotations/ut_annotation_obj_cache_info.tps
index 1db3fd190..5436a11ed 100644
--- a/source/core/annotations/ut_annotation_obj_cache_info.tps
+++ b/source/core/annotations/ut_annotation_obj_cache_info.tps
@@ -1,7 +1,7 @@
-create type ut_annotation_obj_cache_info as object(
+create or replace noneditionable type ut_annotation_obj_cache_info as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_objs_cache_info.tps b/source/core/annotations/ut_annotation_objs_cache_info.tps
index fc96e7d25..c29b7d208 100644
--- a/source/core/annotations/ut_annotation_objs_cache_info.tps
+++ b/source/core/annotations/ut_annotation_objs_cache_info.tps
@@ -1,7 +1,7 @@
-create type ut_annotation_objs_cache_info as
+create or replace noneditionable type ut_annotation_objs_cache_info as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_parser.pkb b/source/core/annotations/ut_annotation_parser.pkb
index f0271c957..5680d3cd2 100644
--- a/source/core/annotations/ut_annotation_parser.pkb
+++ b/source/core/annotations/ut_annotation_parser.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_annotation_parser as
+create or replace noneditionable package body ut_annotation_parser as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -22,12 +22,10 @@ create or replace package body ut_annotation_parser as
type tt_comment_list is table of varchar2(32767) index by binary_integer;
gc_annotation_qualifier constant varchar2(1) := '%';
- gc_annot_comment_pattern constant varchar2(30) := '^( |'||chr(09)||')*-- *('||gc_annotation_qualifier||'.*?)$'; -- chr(09) is a tab character
gc_comment_replacer_patter constant varchar2(50) := '{COMMENT#%N%}';
gc_comment_replacer_regex_ptrn constant varchar2(25) := '{COMMENT#(\d+)}';
- gc_regexp_identifier constant varchar2(50) := '[a-zA-Z][a-zA-Z0-9#_$]*';
- gc_annotation_block_pattern constant varchar2(200) := '(({COMMENT#.+}'||chr(10)||')+)( |'||chr(09)||')*(procedure|function)\s+(' ||
- gc_regexp_identifier || ')';
+ gc_regexp_identifier constant varchar2(50) := '[[:alpha:]][[:alnum:]$#_]*';
+
gc_annotation_pattern constant varchar2(50) := gc_annotation_qualifier || gc_regexp_identifier || '[ '||chr(9)||']*(\(.*?\)\s*?$)?';
@@ -72,133 +70,144 @@ create or replace package body ut_annotation_parser as
a_subobject_name varchar2 := null
) is
l_loop_index binary_integer := 1;
- l_annotation_index binary_integer;
+ l_annotation_index binary_integer := 1;
begin
- -- loop while there are unprocessed comment blocks
- while 0 != nvl(regexp_instr(srcstr => a_source
- ,pattern => gc_comment_replacer_regex_ptrn
- ,occurrence => l_loop_index
- ,subexpression => 1)
- ,0) loop
+ -- loop while there are unprocessed comment blocks
+ while l_annotation_index is not null loop
-- define index of the comment block and get it's content from cache
l_annotation_index := regexp_substr( a_source ,gc_comment_replacer_regex_ptrn ,1 ,l_loop_index ,subexpression => 1);
- add_annotation( a_annotations, l_annotation_index, a_comments( l_annotation_index ), a_subobject_name );
- l_loop_index := l_loop_index + 1;
+ if l_annotation_index is not null then
+ add_annotation( a_annotations, l_annotation_index, a_comments( l_annotation_index ), a_subobject_name );
+ l_loop_index := l_loop_index + 1;
+ end if;
end loop;
end add_annotations;
- procedure add_procedure_annotations(a_annotations in out nocopy ut_annotations, a_source clob, a_comments in out nocopy tt_comment_list) is
- l_proc_comments varchar2(32767);
- l_proc_name varchar2(250);
- l_annot_proc_ind number;
- l_annot_proc_block varchar2(32767);
+ procedure add_procedure_annotations(
+ a_annotations in out nocopy ut_annotations,
+ a_source in dbms_preprocessor.source_lines_t,
+ a_comments in out nocopy tt_comment_list
+ ) is
+ l_proc_comments varchar2(32767);
+ l_proc_name varchar2(250);
+ l_line varchar2(32767);
+ l_in_comment_block boolean := false;
+ l_i binary_integer;
begin
- -- loop through procedures and functions of the package and get all the comment blocks just before it's declaration
- l_annot_proc_ind := 1;
- loop
- --find annotated procedure index
- l_annot_proc_ind := regexp_instr(srcstr => a_source
- ,pattern => gc_annotation_block_pattern
- ,occurrence => 1
- ,modifier => 'i'
- ,position => l_annot_proc_ind);
- exit when l_annot_proc_ind = 0;
-
- --get the annotations with procedure name
- l_annot_proc_block := regexp_substr(srcstr => a_source
- ,pattern => gc_annotation_block_pattern
- ,position => l_annot_proc_ind
- ,occurrence => 1
- ,modifier => 'i');
-
- --extract the annotations
- l_proc_comments := trim(regexp_substr(srcstr => l_annot_proc_block
- ,pattern => gc_annotation_block_pattern
- ,modifier => 'i'
- ,subexpression => 1));
- --extract the procedure name
- l_proc_name := trim(regexp_substr(srcstr => l_annot_proc_block
- ,pattern => gc_annotation_block_pattern
- ,modifier => 'i'
- ,subexpression => 5));
-
- -- parse the comment block for the syntactically correct annotations and store them as an array
- add_annotations(a_annotations, l_proc_comments, a_comments, l_proc_name);
-
- l_annot_proc_ind := instr(a_source, ';', l_annot_proc_ind + length(l_annot_proc_block) );
+ l_i := 1;
+ while l_i <= a_source.count loop
+ l_line := a_source(l_i);
+ -- Comment placeholder line: start/continue accumulating a block
+ if instr(l_line, chr(123) ||'COMMENT#') > 0 then
+ if l_in_comment_block then
+ l_proc_comments := l_proc_comments || l_line || chr(10);
+ else
+ l_in_comment_block := true;
+ l_proc_comments := l_line || chr(10);
+ end if;
+ l_i := l_i + 1;
+ -- Whitespace-only line: allowed between comment block and proc decl
+ elsif l_in_comment_block and trim(replace(l_line, chr(9))) is null then
+ l_i := l_i + 1;
+ -- procedure/function declaration following a comment block
+ elsif l_in_comment_block
+ and regexp_like(l_line, '^\s*(procedure|function)\s+', 'i')
+ then
+ -- extract just the identifier name (subexpression 2)
+ l_proc_name := trim(regexp_substr(srcstr =>l_line
+ ,pattern => '^\s*(procedure|function)\s+('||gc_regexp_identifier||')'
+ ,modifier => 'i'
+ ,subexpression => 2));
+
+ -- pass accumulated comment placeholders + proc name to add_annotations
+ add_annotations(a_annotations, l_proc_comments, a_comments, l_proc_name);
+
+ -- reset comment block state
+ l_in_comment_block := false;
+ l_proc_comments := null;
+
+ -- advance past proc header to the terminating ';'
+ -- the header may span multiple lines e.g. with multi-line parameter lists
+ while l_i <= a_source.count loop
+ exit when instr(a_source(l_i), ';') > 0;
+ l_i := l_i + 1;
+ end loop;
+ l_i := l_i + 1; -- step past the ';' line itself
+ -- Any other line: reset comment block accumulator
+ else
+ l_in_comment_block := false;
+ l_proc_comments := null;
+ l_i := l_i + 1;
+ end if;
end loop;
end add_procedure_annotations;
- function extract_and_replace_comments(a_source in out nocopy clob) return tt_comment_list is
- l_comments tt_comment_list;
- l_comment_pos binary_integer;
- l_comment_line binary_integer;
+ function extract_and_replace_comments(
+ a_source in out nocopy dbms_preprocessor.source_lines_t
+ ) return tt_comment_list is
+ l_comments tt_comment_list;
+ l_line varchar2(32767);
+ l_comment_pos binary_integer;
l_comment_replacer varchar2(50);
- l_source clob := a_source;
begin
- l_comment_pos := 1;
- loop
-
- l_comment_pos := regexp_instr(srcstr => a_source
- ,pattern => gc_annot_comment_pattern
- ,occurrence => 1
- ,modifier => 'm'
- ,position => l_comment_pos);
-
- exit when l_comment_pos = 0;
-
- -- position index is shifted by 1 because gc_annot_comment_pattern contains ^ as first sign
- -- but after instr index already points to the char on that line
- l_comment_pos := l_comment_pos-1;
- l_comment_line := length(substr(a_source,1,l_comment_pos))-length(replace(substr(a_source,1,l_comment_pos),chr(10)))+1;
- l_comments(l_comment_line) := trim(regexp_substr(srcstr => a_source
- ,pattern => gc_annot_comment_pattern
- ,occurrence => 1
- ,position => l_comment_pos
- ,modifier => 'm'
- ,subexpression => 2));
-
- l_comment_replacer := replace(gc_comment_replacer_patter, '%N%', l_comment_line);
-
- l_source := regexp_replace(srcstr => a_source
- ,pattern => gc_annot_comment_pattern
- ,replacestr => l_comment_replacer
- ,position => l_comment_pos
- ,occurrence => 1
- ,modifier => 'm');
- dbms_lob.freetemporary(a_source);
- a_source := l_source;
- dbms_lob.freetemporary(l_source);
- l_comment_pos := l_comment_pos + length(l_comment_replacer);
+ for i in 1 .. a_source.count loop
+ l_line := a_source(i);
+
+ -- fast path: skip lines that can't possibly match
+ -- must contain '--' and '%' to be an annotation comment
+ if instr(l_line, '--') = 0 or instr(l_line, gc_annotation_qualifier) = 0 then
+ continue;
+ end if;
+
+ -- find '--' on the line
+ l_comment_pos := instr(l_line, '--');
+
+ -- verify everything before '--' is only spaces/tabs (matches ^ *( |\t)*--)
+ if trim(replace(substr(l_line, 1, l_comment_pos - 1), chr(9))) is not null then
+ continue;
+ end if;
+
+ -- skip '--' and any spaces after it, then check for annotation qualifier '%'
+ l_comment_pos := l_comment_pos + 2;
+ -- skip optional spaces between -- and %
+ while l_comment_pos <= length(l_line)
+ and substr(l_line, l_comment_pos, 1) = ' '
+ loop
+ l_comment_pos := l_comment_pos + 1;
+ end loop;
+
+ -- must start with annotation qualifier at this position
+ if substr(l_line, l_comment_pos, 1) != gc_annotation_qualifier then
+ continue;
+ end if;
+
+ -- extract annotation text (from % to end of line, trimmed)
+ l_comments(i) := trim(substr(l_line, l_comment_pos));
+
+ -- replace line with placeholder, preserving line number in token
+ l_comment_replacer := replace(gc_comment_replacer_patter, '%N%', i);
+ a_source(i) := l_comment_replacer;
end loop;
- ut_utils.debug_log(a_source);
return l_comments;
end extract_and_replace_comments;
------------------------------------------------------------
--public definitions
------------------------------------------------------------
-
- function parse_object_annotations(a_source clob) return ut_annotations is
- l_source clob := a_source;
+ function parse_object_annotations(a_source dbms_preprocessor.source_lines_t) return ut_annotations is
+ l_source dbms_preprocessor.source_lines_t := a_source;
l_comments tt_comment_list;
l_annotations ut_annotations := ut_annotations();
l_result ut_annotations;
l_comment_index positive;
begin
-
- l_source := ut_utils.replace_multiline_comments(l_source);
-
- -- replace all single line comments with {COMMENT#12} element and store it's content for easier processing
- -- this call modifies l_source
+ l_source := ut_utils.replace_multiline_comments(l_source);
l_comments := extract_and_replace_comments(l_source);
-
add_procedure_annotations(l_annotations, l_source, l_comments);
-
delete_processed_comments(l_comments, l_annotations);
--at this point, only the comments not related to procedures are left, so we process them all as top-level
@@ -208,16 +217,15 @@ create or replace package body ut_annotation_parser as
l_comment_index := l_comments.next(l_comment_index);
end loop;
- dbms_lob.freetemporary(l_source);
-
- select /*+ no_parallel */ value(x) bulk collect into l_result from table(l_annotations) x order by x.position;
+ select /*+ no_parallel */ value(x) bulk collect into l_result from table(l_annotations) x order by x.position asc;
return l_result;
+
end parse_object_annotations;
function parse_object_annotations(a_source_lines dbms_preprocessor.source_lines_t, a_object_type varchar2) return ut_annotations is
l_processed_lines dbms_preprocessor.source_lines_t;
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_annotations ut_annotations := ut_annotations();
ex_package_is_wrapped exception;
pragma exception_init(ex_package_is_wrapped, -24241);
@@ -233,13 +241,11 @@ create or replace package body ut_annotation_parser as
else
l_processed_lines := sys.dbms_preprocessor.get_post_processed_source(a_source_lines);
end if;
- --convert to clob
for i in 1..l_processed_lines.count loop
- ut_utils.append_to_clob(l_source, replace(l_processed_lines(i), chr(13)||chr(10), chr(10)));
+ l_source(i) := replace(l_processed_lines(i), chr(13)||chr(10), chr(10));
end loop;
--parse annotations
l_annotations := parse_object_annotations(l_source);
- dbms_lob.freetemporary(l_source);
exception
when ex_package_is_wrapped or source_text_is_empty then
null;
diff --git a/source/core/annotations/ut_annotation_parser.pks b/source/core/annotations/ut_annotation_parser.pks
index 2f474c883..3e0eaf84c 100644
--- a/source/core/annotations/ut_annotation_parser.pks
+++ b/source/core/annotations/ut_annotation_parser.pks
@@ -1,7 +1,7 @@
-create or replace package ut_annotation_parser authid current_user as
+create or replace noneditionable package ut_annotation_parser authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -29,16 +29,5 @@ create or replace package ut_annotation_parser authid current_user as
*/
function parse_object_annotations(a_source_lines dbms_preprocessor.source_lines_t, a_object_type varchar2) return ut_annotations;
-
- /**
- *
- * @private
- * Parses source code and converts it to annotations
- *
- * @param a_source_lines ordered lines of source code to be parsed
- * @return array containing annotations
- */
- function parse_object_annotations(a_source clob) return ut_annotations;
-
end;
/
diff --git a/source/core/annotations/ut_annotations.tps b/source/core/annotations/ut_annotations.tps
index a6579d236..9e4adc5ae 100644
--- a/source/core/annotations/ut_annotations.tps
+++ b/source/core/annotations/ut_annotations.tps
@@ -1,7 +1,7 @@
-create type ut_annotations
+create or replace noneditionable type ut_annotations
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_trigger_annotation_parsing.trg b/source/core/annotations/ut_trigger_annotation_parsing.trg
index 437b7742d..75caea5e8 100644
--- a/source/core/annotations/ut_trigger_annotation_parsing.trg
+++ b/source/core/annotations/ut_trigger_annotation_parsing.trg
@@ -2,6 +2,22 @@ create or replace trigger ut_trigger_annotation_parsing
after create or alter or drop
on database
begin
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
if (ora_dict_obj_owner = UPPER('&&UT3_OWNER')
and ora_dict_obj_name = 'UT3_TRIGGER_ALIVE'
and ora_dict_obj_type = 'SYNONYM')
diff --git a/source/core/annotations/ut_trigger_check.pkb b/source/core/annotations/ut_trigger_check.pkb
index 34e43ba46..463243c5e 100644
--- a/source/core/annotations/ut_trigger_check.pkb
+++ b/source/core/annotations/ut_trigger_check.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_trigger_check is
+create or replace noneditionable package body ut_trigger_check is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ create or replace package body ut_trigger_check is
function is_alive return boolean is
pragma autonomous_transaction;
begin
- execute immediate 'create or replace synonym '||ut_utils.ut_owner||'.'||gc_check_object_name||' for no_object';
+ execute immediate 'create or replace noneditionable synonym '||ut_utils.ut_owner||'.'||gc_check_object_name||' for no_object';
return g_is_trigger_live;
end;
diff --git a/source/core/annotations/ut_trigger_check.pks b/source/core/annotations/ut_trigger_check.pks
index cee0b06fd..dae59f3aa 100644
--- a/source/core/annotations/ut_trigger_check.pks
+++ b/source/core/annotations/ut_trigger_check.pks
@@ -1,7 +1,7 @@
-create or replace package ut_trigger_check authid definer is
+create or replace noneditionable package ut_trigger_check authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb
index f5eccc893..be9b4ad5d 100644
--- a/source/core/coverage/ut_coverage.pkb
+++ b/source/core/coverage/ut_coverage.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage is
+create or replace noneditionable package body ut_coverage is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -55,10 +55,11 @@ create or replace package body ut_coverage is
s.text
from {sources_view} s {join_file_mappings}
where s.type in ('PACKAGE BODY', 'TYPE BODY', 'PROCEDURE', 'FUNCTION', 'TRIGGER')
+ and s.origin_con_id = sys_context('userenv', 'con_id')
{filters}
{regex_exc_filters}
and not exists (
- select /*+ cardinality(el {excuded_objects_cardinality})*/ 1
+ select /*+ cardinality(el {excluded_objects_cardinality})*/ 1
from table(:l_excluded_objects) el
where s.owner = el.owner and s.name = el.name
)
@@ -152,7 +153,7 @@ create or replace package body ut_coverage is
l_result := replace(l_result, '{filters}', l_filters);
l_result := replace(l_result, '{mappings_cardinality}', l_mappings_cardinality);
l_result := replace(l_result, '{skipped_objects_cardinality}', ut_utils.scale_cardinality(cardinality(a_skip_objects)));
- l_result := replace(l_result, '{excuded_objects_cardinality}', ut_utils.scale_cardinality(cardinality(coalesce(a_coverage_options.exclude_objects, ut_object_names()))));
+ l_result := replace(l_result, '{excluded_objects_cardinality}', ut_utils.scale_cardinality(cardinality(coalesce(a_coverage_options.exclude_objects, ut_object_names()))));
l_result := replace(l_result, '{regex_exc_filters}', l_regex_exc_filters);
return l_result;
@@ -167,7 +168,7 @@ create or replace package body ut_coverage is
begin
if not is_develop_mode() then
--skip all the utplsql framework objects and all the unit test packages that could potentially be reported by coverage.
- l_skip_objects := coalesce(ut_utils.get_utplsql_objects_list(),ut_object_names());
+ l_skip_objects := coalesce( ut_utils.get_utplsql_objects_list() multiset union all ut_suite_manager.get_schema_ut_packages(a_coverage_options.schema_names, a_coverage_options.include_schema_expr) , ut_object_names() );
end if;
--Regex exclusion override the standard exclusion objects.
diff --git a/source/core/coverage/ut_coverage.pks b/source/core/coverage/ut_coverage.pks
index 21f3b1f9e..b8bc4e169 100644
--- a/source/core/coverage/ut_coverage.pks
+++ b/source/core/coverage/ut_coverage.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage authid current_user is
+create or replace noneditionable package ut_coverage authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_block.pkb b/source/core/coverage/ut_coverage_block.pkb
index a906b81a3..bfdf13274 100644
--- a/source/core/coverage/ut_coverage_block.pkb
+++ b/source/core/coverage/ut_coverage_block.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_block is
+create or replace noneditionable package body ut_coverage_block is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_block.pks b/source/core/coverage/ut_coverage_block.pks
index 01caca035..9fccb3272 100644
--- a/source/core/coverage/ut_coverage_block.pks
+++ b/source/core/coverage/ut_coverage_block.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage_block authid current_user is
+create or replace noneditionable package ut_coverage_block authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb
index e249b3381..ed1bea2ce 100644
--- a/source/core/coverage/ut_coverage_helper.pkb
+++ b/source/core/coverage/ut_coverage_helper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_helper is
+create or replace noneditionable package body ut_coverage_helper is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks
index cd6ed9ec7..11988d935 100644
--- a/source/core/coverage/ut_coverage_helper.pks
+++ b/source/core/coverage/ut_coverage_helper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage_helper authid definer is
+create or replace noneditionable package ut_coverage_helper authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper_block.pkb b/source/core/coverage/ut_coverage_helper_block.pkb
index fb4d4812e..3abbd54fc 100644
--- a/source/core/coverage/ut_coverage_helper_block.pkb
+++ b/source/core/coverage/ut_coverage_helper_block.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_helper_block is
+create or replace noneditionable package body ut_coverage_helper_block is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper_block.pks b/source/core/coverage/ut_coverage_helper_block.pks
index a147d9f4f..dd8c451d7 100644
--- a/source/core/coverage/ut_coverage_helper_block.pks
+++ b/source/core/coverage/ut_coverage_helper_block.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage_helper_block authid current_user is
+create or replace noneditionable package ut_coverage_helper_block authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper_profiler.pkb b/source/core/coverage/ut_coverage_helper_profiler.pkb
index f29291efb..f98631593 100644
--- a/source/core/coverage/ut_coverage_helper_profiler.pkb
+++ b/source/core/coverage/ut_coverage_helper_profiler.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_helper_profiler is
+create or replace noneditionable package body ut_coverage_helper_profiler is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper_profiler.pks b/source/core/coverage/ut_coverage_helper_profiler.pks
index 0c54a83bf..ca2a44a64 100644
--- a/source/core/coverage/ut_coverage_helper_profiler.pks
+++ b/source/core/coverage/ut_coverage_helper_profiler.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage_helper_profiler authid definer is
+create or replace noneditionable package ut_coverage_helper_profiler authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_profiler.pkb b/source/core/coverage/ut_coverage_profiler.pkb
index 663ceab7f..4e874dabf 100644
--- a/source/core/coverage/ut_coverage_profiler.pkb
+++ b/source/core/coverage/ut_coverage_profiler.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_profiler is
+create or replace noneditionable package body ut_coverage_profiler is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_profiler.pks b/source/core/coverage/ut_coverage_profiler.pks
index 9ce9a27f0..788005e15 100644
--- a/source/core/coverage/ut_coverage_profiler.pks
+++ b/source/core/coverage/ut_coverage_profiler.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage_profiler authid current_user is
+create or replace noneditionable package ut_coverage_profiler authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_reporter_base.tpb b/source/core/coverage/ut_coverage_reporter_base.tpb
index aff4e6560..e86af3795 100644
--- a/source/core/coverage/ut_coverage_reporter_base.tpb
+++ b/source/core/coverage/ut_coverage_reporter_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_coverage_reporter_base is
+create or replace noneditionable type body ut_coverage_reporter_base is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -92,7 +92,6 @@ create or replace type body ut_coverage_reporter_base is
ut_coverage_helper.cleanup_tmp_table();
(l_reporter as ut_output_reporter_base).before_calling_run(null);
l_reporter.after_calling_run( ut_run( a_coverage_options => a_coverage_options, a_client_character_set => a_client_character_set ) );
- l_reporter.on_finalize(null);
for i in (select /*+ no_parallel */ x.text from table(l_reporter.get_lines(1, 1)) x ) loop
pipe row (i.text);
end loop;
@@ -106,7 +105,6 @@ create or replace type body ut_coverage_reporter_base is
ut_coverage_helper.cleanup_tmp_table();
(l_reporter as ut_output_reporter_base).before_calling_run(null);
l_reporter.after_calling_run( ut_run( a_coverage_options => a_coverage_options, a_client_character_set => a_client_character_set ) );
- l_reporter.on_finalize(null);
open l_result for select /*+ no_parallel */ x.text from table(l_reporter.get_lines(1, 1)) x;
return l_result;
end;
diff --git a/source/core/coverage/ut_coverage_reporter_base.tps b/source/core/coverage/ut_coverage_reporter_base.tps
index 305c5d757..c4afe389b 100644
--- a/source/core/coverage/ut_coverage_reporter_base.tps
+++ b/source/core/coverage/ut_coverage_reporter_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_coverage_reporter_base under ut_output_reporter_base(
+create or replace noneditionable type ut_coverage_reporter_base under ut_output_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_sources_tmp.sql b/source/core/coverage/ut_coverage_sources_tmp.sql
index c091d5955..35eb05510 100644
--- a/source/core/coverage/ut_coverage_sources_tmp.sql
+++ b/source/core/coverage/ut_coverage_sources_tmp.sql
@@ -1,7 +1,7 @@
create global temporary table ut_coverage_sources_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/events/ut_event_item.tps b/source/core/events/ut_event_item.tps
index c0ea653ea..d9e1b84fc 100644
--- a/source/core/events/ut_event_item.tps
+++ b/source/core/events/ut_event_item.tps
@@ -1,7 +1,7 @@
-create or replace type ut_event_item authid current_user as object (
+create or replace noneditionable type ut_event_item authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/events/ut_event_listener.tps b/source/core/events/ut_event_listener.tps
index bbcdbf218..7236fd512 100644
--- a/source/core/events/ut_event_listener.tps
+++ b/source/core/events/ut_event_listener.tps
@@ -1,7 +1,7 @@
-create or replace type ut_event_listener authid current_user as object (
+create or replace noneditionable type ut_event_listener authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/events/ut_event_manager.pkb b/source/core/events/ut_event_manager.pkb
index f51019421..50c500d13 100644
--- a/source/core/events/ut_event_manager.pkb
+++ b/source/core/events/ut_event_manager.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_event_manager as
+create or replace noneditionable package body ut_event_manager as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/events/ut_event_manager.pks b/source/core/events/ut_event_manager.pks
index 03b18b728..08db7f5da 100644
--- a/source/core/events/ut_event_manager.pks
+++ b/source/core/events/ut_event_manager.pks
@@ -1,7 +1,7 @@
-create or replace package ut_event_manager authid current_user as
+create or replace noneditionable package ut_event_manager authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_buffer_base.tpb b/source/core/output_buffers/ut_output_buffer_base.tpb
index 6d7964150..8b9c236ef 100644
--- a/source/core/output_buffers/ut_output_buffer_base.tpb
+++ b/source/core/output_buffers/ut_output_buffer_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_output_buffer_base is
+create or replace noneditionable type body ut_output_buffer_base is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -18,24 +18,101 @@ create or replace type body ut_output_buffer_base is
member procedure init(self in out nocopy ut_output_buffer_base, a_output_id raw := null, a_self_type varchar2 := null) is
pragma autonomous_transaction;
- l_exists int;
begin
cleanup_buffer();
self.self_type := coalesce(a_self_type,self.self_type);
self.output_id := coalesce(a_output_id, self.output_id, sys_guid());
self.start_date := coalesce(self.start_date, sysdate);
- self.last_message_id := 0;
- select /*+ no_parallel */ count(*) into l_exists from ut_output_buffer_info_tmp where output_id = self.output_id;
- if ( l_exists > 0 ) then
- update /*+ no_parallel */ ut_output_buffer_info_tmp set start_date = self.start_date where output_id = self.output_id;
- else
- insert /*+ no_parallel */ into ut_output_buffer_info_tmp(output_id, start_date) values (self.output_id, self.start_date);
- end if;
+ merge /*+ no_parallel */ into ut_output_buffer_info_tmp dst
+ using (select 1 from dual) src
+ on (dst.output_id = self.output_id)
+ when matched then
+ update
+ set dst.start_date = self.start_date
+ when not matched then
+ insert (output_id, start_date)
+ values (self.output_id, self.start_date);
commit;
+ dbms_lock.allocate_unique( self.output_id, self.lock_handle);
self.is_closed := 0;
end;
- member function get_lines_cursor(a_initial_timeout natural := null, a_timeout_sec natural := null) return sys_refcursor is
+ member procedure lock_buffer(a_timeout_sec number := null) is
+ l_status integer;
+ begin
+ l_status := dbms_lock.request( self.lock_handle, dbms_lock.x_mode, 5, false );
+ if l_status != 0 then
+ raise_application_error(-20000, 'Cannot allocate lock for output buffer of reporter. lock request status = '||l_status||', lock handle = '||self.lock_handle||', self.output_id ='||self.output_id);
+ end if;
+ end;
+
+ member procedure close(self in out nocopy ut_output_buffer_base) is
+ l_status integer;
+ begin
+ l_status := dbms_lock.release( self.lock_handle );
+ if l_status != 0 then
+ raise_application_error(-20000, 'Cannot release lock for output buffer of reporter. Lock_handle = '||self.lock_handle||' status = '||l_status);
+ end if;
+ self.is_closed := 1;
+ end;
+
+
+ member procedure remove_buffer_info(self in ut_output_buffer_base) is
+ pragma autonomous_transaction;
+ begin
+ delete from ut_output_buffer_info_tmp a
+ where a.output_id = self.output_id;
+ commit;
+ end;
+
+ member function timeout_producer_not_started( a_producer_started boolean, a_already_waited_sec number, a_init_wait_sec number ) return boolean
+ is
+ l_result boolean := false;
+ begin
+ if not a_producer_started and a_already_waited_sec >= a_init_wait_sec then
+ if a_init_wait_sec > 0 then
+ self.remove_buffer_info();
+ raise_application_error(
+ ut_utils.gc_out_buffer_timeout,
+ 'Timeout occurred while waiting for report data producer to start. Waited for: '||ut_utils.to_string( a_already_waited_sec )||' seconds.'
+ );
+ else
+ l_result := true;
+ end if;
+ end if;
+ return l_result;
+ end;
+
+ member function timeout_producer_not_finished(a_producer_finished boolean, a_already_waited_sec number, a_timeout_sec number) return boolean
+ is
+ l_result boolean := false;
+ begin
+ if not a_producer_finished and a_timeout_sec is not null and a_already_waited_sec >= a_timeout_sec then
+ if a_timeout_sec > 0 then
+ self.remove_buffer_info();
+ raise_application_error(
+ ut_utils.gc_out_buffer_timeout,
+ 'Timeout occurred while waiting for more data from producer. Waited for: '||ut_utils.to_string( a_already_waited_sec )||' seconds.'
+ );
+ else
+ l_result := true;
+ end if;
+ end if;
+ return l_result;
+ end;
+
+ member function get_lock_status return integer is
+ l_result integer;
+ l_release_status integer;
+ begin
+ l_result := dbms_lock.request( self.lock_handle, dbms_lock.s_mode, 0, false );
+ if l_result = 0 then
+ l_release_status := dbms_lock.release( self.lock_handle );
+ end if;
+ return l_result;
+ end;
+
+ member function get_lines_cursor(a_initial_timeout number := null, a_timeout_sec number := null) return sys_refcursor is
l_lines sys_refcursor;
begin
open l_lines for
@@ -44,7 +121,7 @@ create or replace type body ut_output_buffer_base is
return l_lines;
end;
- member procedure lines_to_dbms_output(self in ut_output_buffer_base, a_initial_timeout natural := null, a_timeout_sec natural := null) is
+ member procedure lines_to_dbms_output(self in ut_output_buffer_base, a_initial_timeout number := null, a_timeout_sec number := null) is
l_data sys_refcursor;
l_clob clob;
l_item_type varchar2(32767);
@@ -54,16 +131,20 @@ create or replace type body ut_output_buffer_base is
loop
fetch l_data into l_clob, l_item_type;
exit when l_data%notfound;
- l_lines := ut_utils.clob_to_table(l_clob);
- for i in 1 .. l_lines.count loop
- dbms_output.put_line(l_lines(i));
- end loop;
+ if dbms_lob.getlength(l_clob) > 32767 then
+ l_lines := ut_utils.clob_to_table(l_clob);
+ for i in 1 .. l_lines.count loop
+ dbms_output.put_line(l_lines(i));
+ end loop;
+ else
+ dbms_output.put_line(l_clob);
+ end if;
end loop;
close l_data;
end;
member procedure cleanup_buffer(self in ut_output_buffer_base, a_retention_time_sec natural := null) is
- gc_buffer_retention_sec constant naturaln := coalesce(a_retention_time_sec, 60 * 60 * 24); -- 24 hours
+ gc_buffer_retention_sec constant naturaln := coalesce(a_retention_time_sec, 60 * 60 * 24 * 5); -- 5 days
l_retention_days number := gc_buffer_retention_sec / (60 * 60 * 24);
l_max_retention_date date := sysdate - l_retention_days;
pragma autonomous_transaction;
diff --git a/source/core/output_buffers/ut_output_buffer_base.tps b/source/core/output_buffers/ut_output_buffer_base.tps
index 98a6847cd..da2bc9143 100644
--- a/source/core/output_buffers/ut_output_buffer_base.tps
+++ b/source/core/output_buffers/ut_output_buffer_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_buffer_base force authid definer as object(
+create or replace noneditionable type ut_output_buffer_base force authid definer as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -19,16 +19,21 @@ create or replace type ut_output_buffer_base force authid definer as object(
output_id raw(32),
is_closed number(1,0),
start_date date,
- last_message_id number(38,0),
+ lock_handle varchar2(30 byte),
self_type varchar2(250 byte),
member procedure init(self in out nocopy ut_output_buffer_base, a_output_id raw := null, a_self_type varchar2 := null),
- member function get_lines_cursor(a_initial_timeout natural := null, a_timeout_sec natural := null) return sys_refcursor,
- member procedure lines_to_dbms_output(self in ut_output_buffer_base, a_initial_timeout natural := null, a_timeout_sec natural := null),
+ member procedure lock_buffer(a_timeout_sec number := null),
+ member function timeout_producer_not_started( a_producer_started boolean, a_already_waited_sec number, a_init_wait_sec number ) return boolean,
+ member function timeout_producer_not_finished(a_producer_finished boolean, a_already_waited_sec number, a_timeout_sec number) return boolean,
+ member function get_lock_status return integer,
+ member function get_lines_cursor(a_initial_timeout number := null, a_timeout_sec number := null) return sys_refcursor,
+ member procedure lines_to_dbms_output(self in ut_output_buffer_base, a_initial_timeout number := null, a_timeout_sec number := null),
member procedure cleanup_buffer(self in ut_output_buffer_base, a_retention_time_sec natural := null),
- not instantiable member procedure close(self in out nocopy ut_output_buffer_base),
+ member procedure remove_buffer_info(self in ut_output_buffer_base),
+ member procedure close(self in out nocopy ut_output_buffer_base),
not instantiable member procedure send_line(self in out nocopy ut_output_buffer_base, a_text varchar2, a_item_type varchar2 := null),
not instantiable member procedure send_lines(self in out nocopy ut_output_buffer_base, a_text_list ut_varchar2_rows, a_item_type varchar2 := null),
not instantiable member procedure send_clob(self in out nocopy ut_output_buffer_base, a_text clob, a_item_type varchar2 := null),
- not instantiable member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_output_data_rows pipelined
+ not instantiable member function get_lines(a_initial_timeout number := null, a_timeout_sec number := null) return ut_output_data_rows pipelined
) not final not instantiable
/
diff --git a/source/core/output_buffers/ut_output_buffer_info_tmp.sql b/source/core/output_buffers/ut_output_buffer_info_tmp.sql
index af730d394..2aba5a55c 100644
--- a/source/core/output_buffers/ut_output_buffer_info_tmp.sql
+++ b/source/core/output_buffers/ut_output_buffer_info_tmp.sql
@@ -1,7 +1,7 @@
create table ut_output_buffer_info_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/output_buffers/ut_output_buffer_tmp.sql b/source/core/output_buffers/ut_output_buffer_tmp.sql
index 57027817e..68b738d3f 100644
--- a/source/core/output_buffers/ut_output_buffer_tmp.sql
+++ b/source/core/output_buffers/ut_output_buffer_tmp.sql
@@ -1,7 +1,7 @@
create table ut_output_buffer_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
@@ -30,3 +30,4 @@ create table ut_output_buffer_tmp(
) organization index nologging initrans 100
overflow nologging initrans 100;
+create sequence ut_output_buffer_tmp_seq cache 20;
diff --git a/source/core/output_buffers/ut_output_bulk_buffer.tpb b/source/core/output_buffers/ut_output_bulk_buffer.tpb
new file mode 100644
index 000000000..4f6698eaf
--- /dev/null
+++ b/source/core/output_buffers/ut_output_bulk_buffer.tpb
@@ -0,0 +1,160 @@
+create or replace noneditionable type body ut_output_bulk_buffer is
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+ constructor function ut_output_bulk_buffer(self in out nocopy ut_output_bulk_buffer, a_output_id raw := null) return self as result is
+ begin
+ self.init(a_output_id, $$plsql_unit);
+ return;
+ end;
+
+ overriding member procedure send_line(self in out nocopy ut_output_bulk_buffer, a_text varchar2, a_item_type varchar2 := null) is
+ pragma autonomous_transaction;
+ begin
+ if a_text is not null or a_item_type is not null then
+ if length(a_text) > ut_utils.gc_max_storage_varchar2_len then
+ self.send_lines(
+ ut_utils.convert_collection(
+ ut_utils.clob_to_table(a_text, ut_utils.gc_max_storage_varchar2_len)
+ ),
+ a_item_type
+ );
+ else
+ insert /*+ no_parallel */ into ut_output_buffer_tmp(output_id, message_id, text, item_type)
+ values (self.output_id, ut_output_buffer_tmp_seq.nextval, a_text, a_item_type);
+ end if;
+ commit;
+ end if;
+ end;
+
+ overriding member procedure send_lines(self in out nocopy ut_output_bulk_buffer, a_text_list ut_varchar2_rows, a_item_type varchar2 := null) is
+ pragma autonomous_transaction;
+ begin
+ insert /*+ no_parallel */ into ut_output_buffer_tmp(output_id, message_id, text, item_type)
+ select /*+ no_parallel */ self.output_id, ut_output_buffer_tmp_seq.nextval, t.column_value, a_item_type
+ from table(a_text_list) t
+ where t.column_value is not null or a_item_type is not null;
+ commit;
+ end;
+
+ overriding member procedure send_clob(self in out nocopy ut_output_bulk_buffer, a_text clob, a_item_type varchar2 := null) is
+ pragma autonomous_transaction;
+ begin
+ if a_text is not null and a_text != empty_clob() or a_item_type is not null then
+ if length(a_text) > ut_utils.gc_max_storage_varchar2_len then
+ self.send_lines(
+ ut_utils.convert_collection(
+ ut_utils.clob_to_table(a_text, ut_utils.gc_max_storage_varchar2_len)
+ ),
+ a_item_type
+ );
+ else
+ insert /*+ no_parallel */ into ut_output_buffer_tmp(output_id, message_id, text, item_type)
+ values (self.output_id, ut_output_buffer_tmp_seq.nextval, a_text, a_item_type);
+ end if;
+ commit;
+ end if;
+ end;
+
+ overriding member procedure lines_to_dbms_output(self in ut_output_bulk_buffer, a_initial_timeout number := null, a_timeout_sec number := null) is
+ l_data sys_refcursor;
+ l_text ut_varchar2_rows;
+ l_item_type ut_varchar2_rows;
+ begin
+ l_data := self.get_lines_cursor(a_initial_timeout, a_timeout_sec);
+ loop
+ fetch l_data bulk collect into l_text, l_item_type limit 10000;
+ for idx in 1 .. l_text.count loop
+ dbms_output.put_line(l_text(idx));
+ end loop;
+ exit when l_data%notfound;
+ end loop;
+ close l_data;
+ self.remove_buffer_info();
+ end;
+
+ overriding member function get_lines_cursor(a_initial_timeout number := null, a_timeout_sec number := null) return sys_refcursor is
+ lc_init_wait_sec constant number := coalesce(a_initial_timeout, 10 );
+ l_already_waited_sec number(10,2) := 0;
+ l_sleep_time number(2,1);
+ l_exists integer;
+ l_finished boolean := false;
+ l_data_produced boolean := false;
+ l_producer_active boolean := false;
+ l_producer_started boolean := false;
+ l_producer_finished boolean := false;
+ l_results sys_refcursor;
+ begin
+
+ while not l_finished loop
+
+ if not l_data_produced then
+ select /*+ no_parallel */ count(1) into l_exists
+ from ut_output_buffer_tmp o
+ where o.output_id = self.output_id and rownum = 1;
+ l_data_produced := (l_exists = 1);
+ end if;
+
+ l_sleep_time := case when l_already_waited_sec >= 1 then 0.5 else 0.1 end;
+ l_producer_active := (self.get_lock_status() <> 0);
+ l_producer_started := (l_producer_active or l_data_produced ) or l_producer_started;
+ l_producer_finished := (l_producer_started and not l_producer_active) or l_producer_finished;
+ l_finished :=
+ self.timeout_producer_not_finished(l_producer_finished, l_already_waited_sec, a_timeout_sec)
+ or self.timeout_producer_not_started(l_producer_started, l_already_waited_sec, lc_init_wait_sec)
+ or l_producer_finished;
+
+ dbms_lock.sleep(l_sleep_time);
+ l_already_waited_sec := l_already_waited_sec + l_sleep_time;
+ end loop;
+
+ open l_results for
+ select /*+ no_parallel */ o.text, o.item_type
+ from ut_output_buffer_tmp o
+ where o.output_id = self.output_id
+ and o.text is not null
+ order by o.output_id, o.message_id;
+
+ return l_results;
+
+ end;
+
+ /* Important note.
+ This function code is almost duplicated between two types for performance reasons.
+ The pipe row clause is much faster on VARCHAR2 then it is on clob.
+ That is the key reason for two implementations.
+ */
+ overriding member function get_lines(a_initial_timeout number := null, a_timeout_sec number := null) return ut_output_data_rows pipelined is
+ l_data sys_refcursor;
+ l_text ut_varchar2_rows;
+ l_item_type ut_varchar2_rows;
+ begin
+ l_data := self.get_lines_cursor(a_initial_timeout, a_timeout_sec);
+ loop
+ fetch l_data bulk collect into l_text, l_item_type limit 10000;
+ for idx in 1 .. l_text.count loop
+ pipe row( ut_output_data_row(l_text(idx), l_item_type(idx)) );
+ end loop;
+ exit when l_data%notfound;
+ end loop;
+ close l_data;
+ self.remove_buffer_info();
+ return;
+ end;
+
+end;
+/
diff --git a/source/core/output_buffers/ut_output_bulk_buffer.tps b/source/core/output_buffers/ut_output_bulk_buffer.tps
new file mode 100644
index 000000000..538bc12a5
--- /dev/null
+++ b/source/core/output_buffers/ut_output_bulk_buffer.tps
@@ -0,0 +1,27 @@
+create or replace noneditionable type ut_output_bulk_buffer under ut_output_buffer_base (
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+ constructor function ut_output_bulk_buffer(self in out nocopy ut_output_bulk_buffer, a_output_id raw := null) return self as result,
+ overriding member procedure send_line(self in out nocopy ut_output_bulk_buffer, a_text varchar2, a_item_type varchar2 := null),
+ overriding member procedure send_lines(self in out nocopy ut_output_bulk_buffer, a_text_list ut_varchar2_rows, a_item_type varchar2 := null),
+ overriding member procedure send_clob(self in out nocopy ut_output_bulk_buffer, a_text clob, a_item_type varchar2 := null),
+ overriding member procedure lines_to_dbms_output(self in ut_output_bulk_buffer, a_initial_timeout number := null, a_timeout_sec number := null),
+ overriding member function get_lines_cursor(a_initial_timeout number := null, a_timeout_sec number := null) return sys_refcursor,
+ overriding member function get_lines(a_initial_timeout number := null, a_timeout_sec number := null) return ut_output_data_rows pipelined
+) not final
+/
diff --git a/source/core/output_buffers/ut_output_clob_buffer_tmp.sql b/source/core/output_buffers/ut_output_clob_buffer_tmp.sql
index 40dda121f..fa61191ce 100644
--- a/source/core/output_buffers/ut_output_clob_buffer_tmp.sql
+++ b/source/core/output_buffers/ut_output_clob_buffer_tmp.sql
@@ -6,7 +6,7 @@ begin
v_table_sql := 'create table ut_output_clob_buffer_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
@@ -45,3 +45,5 @@ begin
end;
end;
/
+
+create sequence ut_output_clob_buffer_tmp_seq cache 20;
diff --git a/source/core/output_buffers/ut_output_clob_table_buffer.tpb b/source/core/output_buffers/ut_output_clob_table_buffer.tpb
index 66ff71c62..f6d7c9a66 100644
--- a/source/core/output_buffers/ut_output_clob_table_buffer.tpb
+++ b/source/core/output_buffers/ut_output_clob_table_buffer.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_output_clob_table_buffer is
+create or replace noneditionable type body ut_output_clob_table_buffer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -22,23 +22,12 @@ create or replace type body ut_output_clob_table_buffer is
return;
end;
- overriding member procedure close(self in out nocopy ut_output_clob_table_buffer) is
- pragma autonomous_transaction;
- begin
- self.last_message_id := self.last_message_id + 1;
- insert /*+ no_parallel */ into ut_output_clob_buffer_tmp(output_id, message_id, is_finished)
- values (self.output_id, self.last_message_id, 1);
- commit;
- self.is_closed := 1;
- end;
-
overriding member procedure send_line(self in out nocopy ut_output_clob_table_buffer, a_text varchar2, a_item_type varchar2 := null) is
pragma autonomous_transaction;
begin
if a_text is not null or a_item_type is not null then
- self.last_message_id := self.last_message_id + 1;
insert /*+ no_parallel */ into ut_output_clob_buffer_tmp(output_id, message_id, text, item_type)
- values (self.output_id, self.last_message_id, a_text, a_item_type);
+ values (self.output_id, ut_output_clob_buffer_tmp_seq.nextval, a_text, a_item_type);
end if;
commit;
end;
@@ -47,10 +36,9 @@ create or replace type body ut_output_clob_table_buffer is
pragma autonomous_transaction;
begin
insert /*+ no_parallel */ into ut_output_clob_buffer_tmp(output_id, message_id, text, item_type)
- select /*+ no_parallel */ self.output_id, self.last_message_id + rownum, t.column_value, a_item_type
+ select /*+ no_parallel */ self.output_id, ut_output_clob_buffer_tmp_seq.nextval, t.column_value, a_item_type
from table(a_text_list) t
where t.column_value is not null or a_item_type is not null;
- self.last_message_id := self.last_message_id + SQL%rowcount;
commit;
end;
@@ -58,98 +46,87 @@ create or replace type body ut_output_clob_table_buffer is
pragma autonomous_transaction;
begin
if a_text is not null and a_text != empty_clob() or a_item_type is not null then
- self.last_message_id := self.last_message_id + 1;
insert /*+ no_parallel */ into ut_output_clob_buffer_tmp(output_id, message_id, text, item_type)
- values (self.output_id, self.last_message_id, a_text, a_item_type);
+ values (self.output_id, ut_output_clob_buffer_tmp_seq.nextval, a_text, a_item_type);
end if;
commit;
end;
- overriding member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_output_data_rows pipelined is
- type t_rowid_tab is table of urowid;
- l_message_rowids t_rowid_tab;
- l_buffer_data ut_output_data_rows;
- l_finished_flags ut_integer_list;
- l_already_waited_for number(10,2) := 0;
- l_finished boolean := false;
- lc_init_wait_sec constant naturaln := coalesce(a_initial_timeout, 60 ); -- 1 minute
- lc_max_wait_sec constant naturaln := coalesce(a_timeout_sec, 60 * 60 * 4); -- 4 hours
- l_wait_for integer := lc_init_wait_sec;
- lc_short_sleep_time constant number(1,1) := 0.1; --sleep for 100 ms between checks
- lc_long_sleep_time constant number(1) := 1; --sleep for 1 s when waiting long
- lc_long_wait_time constant number(1) := 1; --waiting more than 1 sec
- l_sleep_time number(2,1) := lc_short_sleep_time;
- lc_bulk_limit constant integer := 5000;
- l_max_message_id integer := lc_bulk_limit;
-
- procedure remove_read_data(a_message_rowids t_rowid_tab) is
- pragma autonomous_transaction;
- begin
- forall i in 1 .. a_message_rowids.count
- delete from ut_output_clob_buffer_tmp a
- where rowid = a_message_rowids(i);
- commit;
- end;
-
- procedure remove_buffer_info is
- pragma autonomous_transaction;
- begin
- delete from ut_output_buffer_info_tmp a
- where a.output_id = self.output_id;
- commit;
- end;
-
+ overriding member function get_lines(a_initial_timeout number := null, a_timeout_sec number := null) return ut_output_data_rows pipelined is
+ lc_init_wait_sec constant number := coalesce(a_initial_timeout, 10 );
+ l_buffer_rowids ut_varchar2_rows;
+ l_buffer_data ut_output_data_rows;
+ l_finished_flags ut_integer_list;
+ l_already_waited_sec number(10,2) := 0;
+ l_finished boolean := false;
+ l_sleep_time number(2,1);
+ l_lock_status integer;
+ l_producer_started boolean := false;
+ l_producer_finished boolean := false;
+ procedure get_data_from_buffer_table(
+ a_buffer_data out nocopy ut_output_data_rows,
+ a_buffer_rowids out nocopy ut_varchar2_rows,
+ a_finished_flags out nocopy ut_integer_list
+ ) is
+ lc_bulk_limit constant integer := 5000;
begin
- while not l_finished loop
with ordered_buffer as (
- select /*+ no_parallel index(a) */ a.rowid, ut_output_data_row(a.text, a.item_type), is_finished
+ select /*+ no_parallel index(a) */ ut_output_data_row(a.text, a.item_type), rowidtochar(a.rowid), is_finished
from ut_output_clob_buffer_tmp a
where a.output_id = self.output_id
- and a.message_id <= l_max_message_id
+ and a.message_id <= (select min(message_id) from ut_output_clob_buffer_tmp o where o.output_id = self.output_id) + lc_bulk_limit
order by a.message_id
)
select /*+ no_parallel */ b.*
- bulk collect into l_message_rowids, l_buffer_data, l_finished_flags
+ bulk collect into a_buffer_data, a_buffer_rowids, a_finished_flags
from ordered_buffer b;
+ end;
- --nothing fetched from output, wait and try again
- if l_buffer_data.count = 0 then
- $if dbms_db_version.version >= 18 $then
- dbms_session.sleep(l_sleep_time);
- $else
- dbms_lock.sleep(l_sleep_time);
- $end
- l_already_waited_for := l_already_waited_for + l_sleep_time;
- if l_already_waited_for > lc_long_wait_time then
- l_sleep_time := lc_long_sleep_time;
- end if;
- else
- --reset wait time
- -- we wait lc_max_wait_sec for new message
- l_wait_for := lc_max_wait_sec;
- l_already_waited_for := 0;
- l_sleep_time := lc_short_sleep_time;
+ procedure remove_read_data(a_buffer_rowids ut_varchar2_rows) is
+ pragma autonomous_transaction;
+ begin
+ forall i in 1 .. a_buffer_rowids.count
+ delete from ut_output_clob_buffer_tmp a
+ where rowid = chartorowid(a_buffer_rowids(i));
+ commit;
+ end;
+
+ begin
+ while not l_finished loop
+
+ l_sleep_time := case when l_already_waited_sec >= 1 then 0.5 else 0.1 end;
+ l_lock_status := self.get_lock_status();
+ get_data_from_buffer_table( l_buffer_data, l_buffer_rowids, l_finished_flags );
+
+ if l_buffer_data.count > 0 then
+ l_already_waited_sec := 0;
for i in 1 .. l_buffer_data.count loop
if l_buffer_data(i).text is not null then
- pipe row(l_buffer_data(i));
+ pipe row( l_buffer_data(i) );
elsif l_finished_flags(i) = 1 then
l_finished := true;
exit;
end if;
end loop;
- remove_read_data(l_message_rowids);
- l_max_message_id := l_max_message_id + lc_bulk_limit;
- end if;
- if l_finished or l_already_waited_for >= l_wait_for then
- remove_buffer_info();
- if l_already_waited_for > 0 and l_already_waited_for >= l_wait_for then
- raise_application_error(
- ut_utils.gc_out_buffer_timeout,
- 'Timeout occurred while waiting for output data. Waited for: '||l_already_waited_for||' seconds.'
- );
- end if;
+ remove_read_data(l_buffer_rowids);
+ else
+ --nothing fetched from output, wait.
+ dbms_lock.sleep(l_sleep_time);
+ l_already_waited_sec := l_already_waited_sec + l_sleep_time;
end if;
+
+ l_producer_started := (l_lock_status <> 0 or l_buffer_data.count > 0) or l_producer_started;
+ l_producer_finished := (l_producer_started and l_lock_status = 0 and l_buffer_data.count = 0) or l_producer_finished;
+
+ l_finished :=
+ self.timeout_producer_not_finished(l_producer_finished, l_already_waited_sec, a_timeout_sec)
+ or self.timeout_producer_not_started(l_producer_started, l_already_waited_sec, lc_init_wait_sec)
+ or l_producer_finished
+ or l_finished;
+
end loop;
+
+ self.remove_buffer_info();
return;
end;
diff --git a/source/core/output_buffers/ut_output_clob_table_buffer.tps b/source/core/output_buffers/ut_output_clob_table_buffer.tps
index 7b98efaba..b254c1f47 100644
--- a/source/core/output_buffers/ut_output_clob_table_buffer.tps
+++ b/source/core/output_buffers/ut_output_clob_table_buffer.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_clob_table_buffer under ut_output_buffer_base (
+create or replace noneditionable type ut_output_clob_table_buffer under ut_output_buffer_base (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ create or replace type ut_output_clob_table_buffer under ut_output_buffer_base (
overriding member procedure send_line(self in out nocopy ut_output_clob_table_buffer, a_text varchar2, a_item_type varchar2 := null),
overriding member procedure send_lines(self in out nocopy ut_output_clob_table_buffer, a_text_list ut_varchar2_rows, a_item_type varchar2 := null),
overriding member procedure send_clob(self in out nocopy ut_output_clob_table_buffer, a_text clob, a_item_type varchar2 := null),
- overriding member procedure close(self in out nocopy ut_output_clob_table_buffer),
- overriding member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_output_data_rows pipelined
+ overriding member function get_lines(a_initial_timeout number := null, a_timeout_sec number := null) return ut_output_data_rows pipelined
) not final
/
diff --git a/source/core/output_buffers/ut_output_data_row.tps b/source/core/output_buffers/ut_output_data_row.tps
index c5dd95e98..2eed2ee1f 100644
--- a/source/core/output_buffers/ut_output_data_row.tps
+++ b/source/core/output_buffers/ut_output_data_row.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_data_row as object (
+create or replace noneditionable type ut_output_data_row as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_data_rows.tps b/source/core/output_buffers/ut_output_data_rows.tps
index 097e9beff..a10440617 100644
--- a/source/core/output_buffers/ut_output_data_rows.tps
+++ b/source/core/output_buffers/ut_output_data_rows.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_data_rows as
+create or replace noneditionable type ut_output_data_rows as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_table_buffer.tpb b/source/core/output_buffers/ut_output_table_buffer.tpb
index 1809a49d5..d87362572 100644
--- a/source/core/output_buffers/ut_output_table_buffer.tpb
+++ b/source/core/output_buffers/ut_output_table_buffer.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_output_table_buffer is
+create or replace noneditionable type body ut_output_table_buffer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -22,21 +22,11 @@ create or replace type body ut_output_table_buffer is
return;
end;
- overriding member procedure close(self in out nocopy ut_output_table_buffer) is
- pragma autonomous_transaction;
- begin
- self.last_message_id := self.last_message_id + 1;
- insert /*+ no_parallel */ into ut_output_buffer_tmp(output_id, message_id, is_finished)
- values (self.output_id, self.last_message_id, 1);
- commit;
- self.is_closed := 1;
- end;
-
overriding member procedure send_line(self in out nocopy ut_output_table_buffer, a_text varchar2, a_item_type varchar2 := null) is
pragma autonomous_transaction;
begin
if a_text is not null or a_item_type is not null then
- if length(a_text) > ut_utils.gc_max_storage_varchar2_len then
+ if lengthb(a_text) > ut_utils.gc_max_storage_varchar2_len then
self.send_lines(
ut_utils.convert_collection(
ut_utils.clob_to_table(a_text, ut_utils.gc_max_storage_varchar2_len)
@@ -44,9 +34,8 @@ create or replace type body ut_output_table_buffer is
a_item_type
);
else
- self.last_message_id := self.last_message_id + 1;
insert /*+ no_parallel */ into ut_output_buffer_tmp(output_id, message_id, text, item_type)
- values (self.output_id, self.last_message_id, a_text, a_item_type);
+ values (self.output_id, ut_output_buffer_tmp_seq.nextval, a_text, a_item_type);
end if;
commit;
end if;
@@ -56,10 +45,9 @@ create or replace type body ut_output_table_buffer is
pragma autonomous_transaction;
begin
insert /*+ no_parallel */ into ut_output_buffer_tmp(output_id, message_id, text, item_type)
- select /*+ no_parallel */ self.output_id, self.last_message_id + rownum, t.column_value, a_item_type
+ select /*+ no_parallel */ self.output_id, ut_output_buffer_tmp_seq.nextval, t.column_value, a_item_type
from table(a_text_list) t
where t.column_value is not null or a_item_type is not null;
- self.last_message_id := self.last_message_id + SQL%rowcount;
commit;
end;
@@ -67,7 +55,7 @@ create or replace type body ut_output_table_buffer is
pragma autonomous_transaction;
begin
if a_text is not null and a_text != empty_clob() or a_item_type is not null then
- if length(a_text) > ut_utils.gc_max_storage_varchar2_len then
+ if ut_utils.lengthb_clob(a_text) > ut_utils.gc_max_storage_varchar2_len then
self.send_lines(
ut_utils.convert_collection(
ut_utils.clob_to_table(a_text, ut_utils.gc_max_storage_varchar2_len)
@@ -75,99 +63,100 @@ create or replace type body ut_output_table_buffer is
a_item_type
);
else
- self.last_message_id := self.last_message_id + 1;
insert /*+ no_parallel */ into ut_output_buffer_tmp(output_id, message_id, text, item_type)
- values (self.output_id, self.last_message_id, a_text, a_item_type);
+ values (self.output_id, ut_output_buffer_tmp_seq.nextval, a_text, a_item_type);
end if;
commit;
end if;
end;
- overriding member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_output_data_rows pipelined is
- l_buffer_data ut_varchar2_rows;
- l_item_types ut_varchar2_rows;
- l_finished_flags ut_integer_list;
- l_already_waited_for number(10,2) := 0;
- l_finished boolean := false;
- lc_init_wait_sec constant naturaln := coalesce(a_initial_timeout, 60 ); -- 1 minute
- lc_max_wait_sec constant naturaln := coalesce(a_timeout_sec, 60 * 60 * 4); -- 4 hours
- l_wait_for integer := lc_init_wait_sec;
- lc_short_sleep_time constant number(1,1) := 0.1; --sleep for 100 ms between checks
- lc_long_sleep_time constant number(1) := 1; --sleep for 1 s when waiting long
- lc_long_wait_time constant number(1) := 1; --waiting more than 1 sec
- l_sleep_time number(2,1) := lc_short_sleep_time;
- lc_bulk_limit constant integer := 5000;
- l_max_message_id integer := lc_bulk_limit;
-
- procedure get_data_from_buffer(
- a_max_message_id integer,
- a_buffer_data out nocopy ut_varchar2_rows,
- a_item_types out nocopy ut_varchar2_rows,
- a_finished_flags out nocopy ut_integer_list
- ) is
- pragma autonomous_transaction;
- begin
- delete /*+ no_parallel */ from (
- select /*+ no_parallel */ *
- from ut_output_buffer_tmp o
- where o.output_id = self.output_id
- and o.message_id <= a_max_message_id
- order by o.message_id
- ) d
- returning d.text, d.item_type, d.is_finished
- bulk collect into a_buffer_data, a_item_types, a_finished_flags;
- commit;
-
- end;
-
- procedure remove_buffer_info is
- pragma autonomous_transaction;
- begin
- delete from ut_output_buffer_info_tmp a
- where a.output_id = self.output_id;
- commit;
- end;
+ overriding member procedure lines_to_dbms_output(self in ut_output_table_buffer, a_initial_timeout number := null, a_timeout_sec number := null) is
+ l_data sys_refcursor;
+ l_text ut_varchar2_rows;
+ l_item_type ut_varchar2_rows;
+ begin
+ l_data := self.get_lines_cursor(a_initial_timeout, a_timeout_sec);
+ loop
+ fetch l_data bulk collect into l_text, l_item_type limit 10000;
+ for idx in 1 .. l_text.count loop
+ dbms_output.put_line(l_text(idx));
+ end loop;
+ exit when l_data%notfound;
+ end loop;
+ close l_data;
+ end;
- begin
+ /* Important note.
+ This function code is almost duplicated between two types for performance reasons.
+ The pipe row clause is much faster on VARCHAR2 then it is on clob.
+ That is the key reason for two implementations.
+ */
+ overriding member function get_lines(a_initial_timeout number := null, a_timeout_sec number := null) return ut_output_data_rows pipelined is
+ lc_init_wait_sec constant number := coalesce(a_initial_timeout, 10 );
+ l_buffer_texts ut_varchar2_rows;
+ l_buffer_item_types ut_varchar2_rows;
+ l_finished_flags ut_integer_list;
+ l_already_waited_sec number(10,2) := 0;
+ l_finished boolean := false;
+ l_sleep_time number(2,1);
+ l_lock_status integer;
+ l_producer_started boolean := false;
+ l_producer_finished boolean := false;
+
+ procedure get_data_from_buffer_table(
+ a_buffer_texts out nocopy ut_varchar2_rows,
+ a_buffer_item_types out nocopy ut_varchar2_rows,
+ a_finished_flags out nocopy ut_integer_list
+ ) is
+ lc_bulk_limit constant integer := 20000;
+ pragma autonomous_transaction;
+ begin
+ delete /*+ no_parallel */ from (
+ select /*+ no_parallel */ *
+ from ut_output_buffer_tmp a
+ where a.output_id = self.output_id
+ and a.message_id <= (select min(message_id) from ut_output_buffer_tmp o where o.output_id = self.output_id) + lc_bulk_limit
+ order by a.message_id
+ ) d
+ returning d.text, d.item_type, d.is_finished
+ bulk collect into a_buffer_texts, a_buffer_item_types, a_finished_flags;
+ commit;
+ end;
+ begin
while not l_finished loop
- get_data_from_buffer( l_max_message_id, l_buffer_data, l_item_types, l_finished_flags);
- --nothing fetched from output, wait and try again
- if l_buffer_data.count = 0 then
- $if dbms_db_version.version >= 18 $then
- dbms_session.sleep(l_sleep_time);
- $else
- dbms_lock.sleep(l_sleep_time);
- $end
- l_already_waited_for := l_already_waited_for + l_sleep_time;
- if l_already_waited_for > lc_long_wait_time then
- l_sleep_time := lc_long_sleep_time;
- end if;
- else
- --reset wait time
- -- we wait lc_max_wait_sec for new message
- l_wait_for := lc_max_wait_sec;
- l_already_waited_for := 0;
- l_sleep_time := lc_short_sleep_time;
- for i in 1 .. l_buffer_data.count loop
- if l_buffer_data(i) is not null then
- pipe row(ut_output_data_row(l_buffer_data(i),l_item_types(i)));
+
+ l_sleep_time := case when l_already_waited_sec >= 1 then 0.5 else 0.1 end;
+ l_lock_status := self.get_lock_status();
+ get_data_from_buffer_table( l_buffer_texts, l_buffer_item_types, l_finished_flags );
+
+ if l_buffer_texts.count > 0 then
+ l_already_waited_sec := 0;
+ for i in 1 .. l_buffer_texts.count loop
+ if l_buffer_texts(i) is not null then
+ pipe row( ut_output_data_row(l_buffer_texts(i), l_buffer_item_types(i)) );
elsif l_finished_flags(i) = 1 then
l_finished := true;
exit;
end if;
end loop;
- l_max_message_id := l_max_message_id + lc_bulk_limit;
- end if;
- if l_finished or l_already_waited_for >= l_wait_for then
- remove_buffer_info();
- if l_already_waited_for > 0 and l_already_waited_for >= l_wait_for then
- raise_application_error(
- ut_utils.gc_out_buffer_timeout,
- 'Timeout occurred while waiting for output data. Waited for: '||l_already_waited_for||' seconds.'
- );
- end if;
+ else
+ --nothing fetched from output, wait.
+ dbms_lock.sleep(l_sleep_time);
+ l_already_waited_sec := l_already_waited_sec + l_sleep_time;
end if;
+
+ l_producer_started := (l_lock_status <> 0 or l_buffer_texts.count > 0) or l_producer_started;
+ l_producer_finished := (l_producer_started and l_lock_status = 0 and l_buffer_texts.count = 0) or l_producer_finished;
+
+ l_finished :=
+ self.timeout_producer_not_finished(l_producer_finished, l_already_waited_sec, a_timeout_sec)
+ or self.timeout_producer_not_started(l_producer_started, l_already_waited_sec, lc_init_wait_sec)
+ or l_producer_finished
+ or l_finished;
+
end loop;
+
+ self.remove_buffer_info();
return;
end;
diff --git a/source/core/output_buffers/ut_output_table_buffer.tps b/source/core/output_buffers/ut_output_table_buffer.tps
index 726b692f8..3f13e736d 100644
--- a/source/core/output_buffers/ut_output_table_buffer.tps
+++ b/source/core/output_buffers/ut_output_table_buffer.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_table_buffer under ut_output_buffer_base (
+create or replace noneditionable type ut_output_table_buffer under ut_output_buffer_base (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ create or replace type ut_output_table_buffer under ut_output_buffer_base (
overriding member procedure send_line(self in out nocopy ut_output_table_buffer, a_text varchar2, a_item_type varchar2 := null),
overriding member procedure send_lines(self in out nocopy ut_output_table_buffer, a_text_list ut_varchar2_rows, a_item_type varchar2 := null),
overriding member procedure send_clob(self in out nocopy ut_output_table_buffer, a_text clob, a_item_type varchar2 := null),
- overriding member procedure close(self in out nocopy ut_output_table_buffer),
- overriding member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_output_data_rows pipelined
+ overriding member procedure lines_to_dbms_output(self in ut_output_table_buffer, a_initial_timeout number := null, a_timeout_sec number := null),
+ overriding member function get_lines(a_initial_timeout number := null, a_timeout_sec number := null) return ut_output_data_rows pipelined
) not final
/
diff --git a/source/core/session_context/ut_session_context.pkb b/source/core/session_context/ut_session_context.pkb
index a97505e9c..12d104eed 100644
--- a/source/core/session_context/ut_session_context.pkb
+++ b/source/core/session_context/ut_session_context.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_session_context as
+create or replace noneditionable package body ut_session_context as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/session_context/ut_session_context.pks b/source/core/session_context/ut_session_context.pks
index 63da3399e..a5e4038a0 100644
--- a/source/core/session_context/ut_session_context.pks
+++ b/source/core/session_context/ut_session_context.pks
@@ -1,7 +1,7 @@
-create or replace package ut_session_context as
+create or replace noneditionable package ut_session_context as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/session_context/ut_session_info.tpb b/source/core/session_context/ut_session_info.tpb
index 7d469651a..14f52b003 100644
--- a/source/core/session_context/ut_session_info.tpb
+++ b/source/core/session_context/ut_session_info.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_session_info as
+create or replace noneditionable type body ut_session_info as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/session_context/ut_session_info.tps b/source/core/session_context/ut_session_info.tps
index 17e596d88..d682a6bad 100644
--- a/source/core/session_context/ut_session_info.tps
+++ b/source/core/session_context/ut_session_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_session_info under ut_event_listener (
+create or replace noneditionable type ut_session_info under ut_event_listener (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_console_reporter_base.tpb b/source/core/types/ut_console_reporter_base.tpb
index 909e9355a..0825b8ba2 100644
--- a/source/core/types/ut_console_reporter_base.tpb
+++ b/source/core/types/ut_console_reporter_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_console_reporter_base is
+create or replace noneditionable type body ut_console_reporter_base is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_console_reporter_base.tps b/source/core/types/ut_console_reporter_base.tps
index a2c4b6b8c..46b344e6e 100644
--- a/source/core/types/ut_console_reporter_base.tps
+++ b/source/core/types/ut_console_reporter_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_console_reporter_base under ut_output_reporter_base(
+create or replace noneditionable type ut_console_reporter_base under ut_output_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_coverage_options.tpb b/source/core/types/ut_coverage_options.tpb
index a091802af..2accd960a 100644
--- a/source/core/types/ut_coverage_options.tpb
+++ b/source/core/types/ut_coverage_options.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_coverage_options as
+create or replace noneditionable type body ut_coverage_options as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_coverage_options.tps b/source/core/types/ut_coverage_options.tps
index a8e3d5129..f2db1dafe 100644
--- a/source/core/types/ut_coverage_options.tps
+++ b/source/core/types/ut_coverage_options.tps
@@ -1,7 +1,7 @@
-create or replace type ut_coverage_options force as object (
+create or replace noneditionable type ut_coverage_options force as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_executable.tpb b/source/core/types/ut_executable.tpb
index d2ce9b79d..2fa3c1b5d 100644
--- a/source/core/types/ut_executable.tpb
+++ b/source/core/types/ut_executable.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_executable is
+create or replace noneditionable type body ut_executable is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -38,20 +38,30 @@ create or replace type body ut_executable is
return ut_metadata.form_name(l_owner_name, object_name, procedure_name);
end;
- member procedure do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item) is
+ member procedure do_execute(
+ self in out nocopy ut_executable,
+ a_item in out nocopy ut_suite_item,
+ a_ignored_exception_names in ut_varchar2_rows := null,
+ a_ignored_exception_numbers in ut_varchar2_rows :=null)
+ is
l_completed_without_errors boolean;
begin
- l_completed_without_errors := self.do_execute(a_item);
+ l_completed_without_errors := self.do_execute(a_item, a_ignored_exception_names, a_ignored_exception_numbers);
end do_execute;
- member function do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item) return boolean is
- l_statement varchar2(4000);
- l_status number;
- l_cursor_number number;
- l_completed_without_errors boolean := true;
- l_failed_with_invalid_pck boolean := true;
- l_start_transaction_id varchar2(250);
- l_end_transaction_id varchar2(250);
+ member function do_execute(
+ self in out nocopy ut_executable,
+ a_item in out nocopy ut_suite_item,
+ a_ignored_exception_names in ut_varchar2_rows := null,
+ a_ignored_exception_numbers in ut_varchar2_rows :=null)
+ return boolean is
+ l_statement varchar2(4000);
+ l_status number;
+ l_cursor_number number;
+ l_completed_without_errors boolean := true;
+ l_failed_with_invalid_pck boolean := true;
+ l_start_transaction_id varchar2(250);
+ l_end_transaction_id varchar2(250);
function is_defined return boolean is
l_result boolean := false;
@@ -111,19 +121,33 @@ create or replace type body ut_executable is
if l_completed_without_errors then
l_statement :=
'declare' || chr(10) ||
- ' l_error_stack varchar2(32767);' || chr(10) ||
- ' l_error_backtrace varchar2(32767);' || chr(10) ||
+ ' l_error_stack varchar2(32767);' || chr(10) ||
+ ' l_error_backtrace varchar2(32767);' || chr(10) ||
+ ' l_ignored_exception_detected integer := 0;' || chr(10) ||
'begin' || chr(10) ||
' begin' || chr(10) ||
' ' || self.form_name( a_skip_current_user_schema => true ) || ';' || chr(10) ||
' exception' || chr(10) ||
+ case when a_ignored_exception_names is not empty then
+ ' when ' || ut_utils.table_to_clob( a_ignored_exception_names, ' or ' ) || ' then ' || chr(10) ||
+ ' l_ignored_exception_detected := 1;'
+ end ||
' when others then ' || chr(10) ||
+ case when a_ignored_exception_numbers is not empty then
+ ' if sqlcode in (' || ut_utils.table_to_clob( a_ignored_exception_numbers, ', ' ) || ') then ' || chr(10) ||
+ ' l_ignored_exception_detected := 1; ' || chr(10) ||
+ ' else ' || chr(10) ||
+ ' l_error_stack := dbms_utility.format_error_stack;' || chr(10) ||
+ ' l_error_backtrace := dbms_utility.format_error_backtrace;' || chr(10) ||
+ ' end if;'
+ else
' l_error_stack := dbms_utility.format_error_stack;' || chr(10) ||
- ' l_error_backtrace := dbms_utility.format_error_backtrace;' || chr(10) ||
- ' --raise on ORA-04068, ORA-04061: existing state of packages has been discarded to avoid unrecoverable session exception' || chr(10) ||
+ ' l_error_backtrace := dbms_utility.format_error_backtrace;'
+ end || chr(10) ||
' end;' || chr(10) ||
' :a_error_stack := l_error_stack;' || chr(10) ||
' :a_error_backtrace := l_error_backtrace;' || chr(10) ||
+ ' :a_ignored_exception_detected := l_ignored_exception_detected;' || chr(10) ||
'end;';
ut_utils.debug_log('ut_executable.do_execute l_statement: ' || l_statement);
@@ -139,9 +163,11 @@ create or replace type body ut_executable is
dbms_sql.parse(l_cursor_number, statement => l_statement, language_flag => dbms_sql.native);
dbms_sql.bind_variable(l_cursor_number, 'a_error_stack', to_char(null), 32767);
dbms_sql.bind_variable(l_cursor_number, 'a_error_backtrace', to_char(null), 32767);
+ dbms_sql.bind_variable(l_cursor_number, 'a_ignored_exception_detected', to_number(null));
l_status := dbms_sql.execute(l_cursor_number);
dbms_sql.variable_value(l_cursor_number, 'a_error_stack', self.error_stack);
dbms_sql.variable_value(l_cursor_number, 'a_error_backtrace', self.error_backtrace);
+ dbms_sql.variable_value(l_cursor_number, 'a_ignored_exception_detected', self.ignored_exception_detected);
dbms_sql.close_cursor(l_cursor_number);
exception
when ut_utils.ex_invalid_package then
diff --git a/source/core/types/ut_executable.tps b/source/core/types/ut_executable.tps
index aaa5a3a72..0945a8996 100644
--- a/source/core/types/ut_executable.tps
+++ b/source/core/types/ut_executable.tps
@@ -1,7 +1,7 @@
-create or replace type ut_executable under ut_event_item(
+create or replace noneditionable type ut_executable under ut_event_item(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -18,26 +18,37 @@ create or replace type ut_executable under ut_event_item(
/**
* The name of the event to be executed before and after the executable is invoked
*/
- executable_type varchar2(250 char),
- owner_name varchar2(250 char),
- object_name varchar2(250 char),
- procedure_name varchar2(250 char),
- error_backtrace varchar2(4000),
- error_stack varchar2(4000),
- serveroutput clob,
+ executable_type varchar2(250 char),
+ owner_name varchar2(250 char),
+ object_name varchar2(250 char),
+ procedure_name varchar2(250 char),
+ error_backtrace varchar2(4000),
+ error_stack varchar2(4000),
+ ignored_exception_detected integer,
+ serveroutput clob,
/**
* Used for ordering of executables, as Oracle doesn not guarantee ordering of items in a nested table.
*/
seq_no integer,
constructor function ut_executable( self in out nocopy ut_executable, a_owner varchar2, a_package varchar2, a_procedure_name varchar2, a_executable_type varchar2) return self as result,
member function form_name(a_skip_current_user_schema boolean := false) return varchar2,
- member procedure do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item),
+ member procedure do_execute(
+ self in out nocopy ut_executable,
+ a_item in out nocopy ut_suite_item,
+ a_ignored_exception_names in ut_varchar2_rows := null,
+ a_ignored_exception_numbers in ut_varchar2_rows := null
+ ),
/**
* executes the defines executable
* returns true if executed without exceptions
* returns false if exceptions were raised
*/
- member function do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item) return boolean,
+ member function do_execute(
+ self in out nocopy ut_executable,
+ a_item in out nocopy ut_suite_item,
+ a_ignored_exception_names in ut_varchar2_rows := null,
+ a_ignored_exception_numbers in ut_varchar2_rows :=null
+ ) return boolean,
member function get_error_stack_trace return varchar2
) not final
/
diff --git a/source/core/types/ut_executable_test.tpb b/source/core/types/ut_executable_test.tpb
index c5a7f29a1..8e48bd70a 100644
--- a/source/core/types/ut_executable_test.tpb
+++ b/source/core/types/ut_executable_test.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_executable_test as
+create or replace noneditionable type body ut_executable_test as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -31,141 +31,129 @@ create or replace type body ut_executable_test as
member procedure do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
- a_expected_error_codes in ut_varchar2_rows
+ a_expected_errors in ut_varchar2_rows
) is
l_completed_without_errors boolean;
begin
- l_completed_without_errors := self.do_execute(a_item, a_expected_error_codes);
+ l_completed_without_errors := self.do_execute(a_item, a_expected_errors);
end do_execute;
member function do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
- a_expected_error_codes in ut_varchar2_rows
+ a_expected_errors in ut_varchar2_rows
) return boolean is
- l_expected_except_message varchar2(4000);
- l_expected_error_numbers ut_integer_list;
-
- function build_exception_numbers_list(
- a_item in out nocopy ut_suite_item,
- a_expected_error_codes in ut_varchar2_rows
- ) return ut_integer_list is
+ l_failure_message varchar2(32767);
+ l_expected_error_names ut_varchar2_rows;
+ l_expected_error_numbers ut_varchar2_rows;
+ l_all_expected_errors ut_varchar2_rows;
+
+ procedure build_expected_exceptions(
+ a_item in out nocopy ut_suite_item,
+ a_exception_definitions in ut_varchar2_rows,
+ a_exception_names_list out ut_varchar2_rows,
+ a_exception_numbers_list out ut_varchar2_rows
+ ) is
l_exception_number integer;
- l_exception_number_list ut_integer_list := ut_integer_list();
- c_regexp_for_exception_no constant varchar2(30) := '^-?[[:digit:]]{1,5}$';
-
- c_integer_exception constant varchar2(1) := 'I';
- c_named_exception constant varchar2(1) := 'N';
-
- function is_valid_qualified_name (a_name varchar2) return boolean is
- l_name varchar2(500);
- begin
- l_name := dbms_assert.qualified_sql_name(a_name);
- return true;
- exception when others then
- return false;
- end;
-
- function check_exception_type(a_exception_name in varchar2) return varchar2 is
- l_exception_type varchar2(50);
- begin
- --check if it is a predefined exception
+ l_exception_name varchar2(128);
+ function to_exception_number (a_exception_var in varchar2, a_item ut_suite_item) return integer is
+ function get_exception_no(a_exception_var in varchar2) return integer is
+ l_exc_no integer;
begin
- execute immediate 'begin null; exception when '||a_exception_name||' then null; end;';
- l_exception_type := c_named_exception;
+ execute immediate 'declare l_exception integer; begin :l_exception := '||a_exception_var||'; end;'
+ using out l_exc_no;
+ return l_exc_no;
exception
when others then
- if dbms_utility.format_error_stack() like '%PLS-00485%' then
- declare
- e_invalid_number exception;
- pragma exception_init ( e_invalid_number, -6502 );
- begin
- execute immediate 'declare x integer := '||a_exception_name||'; begin null; end;';
- l_exception_type := c_integer_exception;
- exception
- when others then
- null;
- end;
- end if;
+ return null;
end;
- return l_exception_type;
- end;
-
- function get_exception_number (a_exception_var in varchar2) return integer is
- l_exc_no integer;
- l_exc_type varchar2(50);
function remap_no_data_found (a_number integer) return integer is
begin
return case a_number when 100 then -1403 else a_number end;
end;
begin
- l_exc_type := check_exception_type(a_exception_var);
-
- execute immediate
- case l_exc_type
- when c_integer_exception then
- 'declare l_exception number; begin :l_exception := '||a_exception_var||'; end;'
- when c_named_exception then
- 'begin raise '||a_exception_var||'; exception when others then :l_exception := sqlcode; end;'
- else
- 'begin :l_exception := null; end;'
- end
- using out l_exc_no;
+ return remap_no_data_found(
+ coalesce(
+ get_exception_no(a_exception_var),
+ get_exception_no(a_item.object_name||'.'||a_exception_var),
+ get_exception_no(a_item.object_owner||'.'||a_exception_var),
+ get_exception_no(a_item.object_owner||'.'||a_item.object_name||'.'||a_exception_var)
+ )
+ );
+ end;
+
+ function to_exception_name (a_exception_var in varchar2, a_item ut_suite_item) return varchar2 is
+ function verify_name(a_exception_name in varchar2) return varchar2 is
+ begin
+ --check if it is an existing, named exception
+ execute immediate 'begin null; exception when '||a_exception_name||' then null; end;';
+ return a_exception_name;
+ exception
+ when others then
+ return null;
+ end;
+ begin
+ return coalesce(
+ verify_name(a_exception_var),
+ verify_name(a_item.object_name||'.'||a_exception_var),
+ verify_name(a_item.object_owner||'.'||a_exception_var),
+ verify_name(a_item.object_owner||'.'||a_item.object_name||'.'||a_exception_var)
+ );
- return remap_no_data_found(l_exc_no);
end;
begin
- if a_expected_error_codes is not empty then
- for i in 1 .. a_expected_error_codes.count loop
- /**
- * Check if its a valid qualified name and if so try to resolve name to an exception number
- */
- if is_valid_qualified_name(a_expected_error_codes(i)) then
- l_exception_number := get_exception_number(a_expected_error_codes(i));
- elsif regexp_like(a_expected_error_codes(i), c_regexp_for_exception_no) then
- l_exception_number := a_expected_error_codes(i);
- end if;
-
- if l_exception_number is null then
+ a_exception_names_list := ut_varchar2_rows();
+ a_exception_numbers_list := ut_varchar2_rows();
+ if a_exception_definitions is not empty then
+ for i in 1 .. a_exception_definitions.count loop
+ l_exception_number :=
+ coalesce(
+ to_exception_number(a_exception_definitions(i), a_item),
+ to_number(a_exception_definitions(i) default null on conversion error )
+ );
+ l_exception_name := to_exception_name(a_exception_definitions(i), a_item);
+
+ if l_exception_number is null and l_exception_name is null then
a_item.put_warning(
- 'Invalid parameter value "'||a_expected_error_codes(i)||'" for "--%throws" annotation. Parameter ignored.',
+ 'Invalid parameter value "'||a_exception_definitions(i)||'" for "--%throws" annotation. Parameter ignored.',
self.procedure_name,
a_item.line_no
);
elsif l_exception_number >= 0 then
a_item.put_warning(
- 'Invalid parameter value "'||a_expected_error_codes(i)||'" for "--%throws" annotation. Exception value must be a negative integer. Parameter ignored.',
+ 'Invalid parameter value "'||a_exception_definitions(i)||'" for "--%throws" annotation. Exception value must be a negative integer. Parameter ignored.',
self.procedure_name,
a_item.line_no
);
- else
- l_exception_number_list.extend;
- l_exception_number_list(l_exception_number_list.last) := l_exception_number;
+ elsif l_exception_number is not null then
+ a_exception_numbers_list.extend;
+ a_exception_numbers_list(a_exception_numbers_list.last) := l_exception_number;
+ elsif l_exception_name is not null then
+ a_exception_names_list.extend;
+ a_exception_names_list(a_exception_names_list.last) := l_exception_name;
end if;
- l_exception_number := null;
end loop;
end if;
-
- return l_exception_number_list;
end;
- function failed_expec_errnum_message(a_expected_error_codes in ut_integer_list) return varchar is
+
+ function get_exception_failure_message(a_expected_errors_list ut_varchar2_rows) return varchar2 is
l_actual_error_no integer;
- l_expected_error_codes varchar2(4000);
+ l_expected_errors varchar2(4000);
l_fail_message varchar2(4000);
begin
--Convert the ut_varchar2_list to string to can construct the message
- l_expected_error_codes := ut_utils.table_to_clob(a_expected_error_codes, ', ');
+ l_expected_errors := ut_utils.table_to_clob(a_expected_errors_list, ', ');
if self.error_stack is null then
- l_fail_message := 'Expected one of exceptions ('||l_expected_error_codes||') but nothing was raised.';
+ l_fail_message := 'Expected one of exceptions ('|| l_expected_errors|| ') but nothing was raised.';
else
- l_actual_error_no := regexp_substr(self.error_stack, '^[a-zA-Z]{3}(-[0-9]+)', subexpression=>1);
- if not l_actual_error_no member of a_expected_error_codes or l_actual_error_no is null then
+ l_actual_error_no := regexp_substr(self.error_stack, '^[[:alpha:]]{3}(-[0-9]+)', subexpression=>1);
+ if not l_actual_error_no member of a_expected_errors_list or l_actual_error_no is null then
l_fail_message := 'Actual: '||l_actual_error_no||' was expected to ';
- if cardinality(a_expected_error_codes) > 1 then
- l_fail_message := l_fail_message || 'be one of: ('||l_expected_error_codes||')';
+ if cardinality(a_expected_errors_list) > 1 then
+ l_fail_message := l_fail_message || 'be one of: ('|| l_expected_errors|| ')';
else
- l_fail_message := l_fail_message || 'equal: '||l_expected_error_codes;
+ l_fail_message := l_fail_message || 'equal: '||l_expected_errors;
end if;
l_fail_message := substr( l_fail_message||chr(10)||self.error_stack||chr(10)||self.error_backtrace, 1, 4000 );
end if;
@@ -175,14 +163,16 @@ create or replace type body ut_executable_test as
end;
begin
--Create a ut_executable object and call do_execute after that get the data to know the test's execution result
- self.do_execute(a_item);
- l_expected_error_numbers := build_exception_numbers_list(a_item, a_expected_error_codes);
- if l_expected_error_numbers is not null and l_expected_error_numbers is not empty then
- l_expected_except_message := failed_expec_errnum_message( l_expected_error_numbers );
+ build_expected_exceptions(a_item, a_expected_errors, l_expected_error_names, l_expected_error_numbers );
+
+ self.do_execute(a_item, l_expected_error_names, l_expected_error_numbers);
+ l_all_expected_errors := l_expected_error_names multiset union all l_expected_error_numbers;
+ if l_all_expected_errors is not empty and self.ignored_exception_detected = 0 then
+ l_failure_message := get_exception_failure_message( l_all_expected_errors);
- if l_expected_except_message is not null then
+ if l_failure_message is not null then
ut_expectation_processor.add_expectation_result(
- ut_expectation_result(ut_utils.gc_failure, null, l_expected_except_message, false)
+ ut_expectation_result(ut_utils.gc_failure, null, l_failure_message, false)
);
end if;
self.error_stack := null;
diff --git a/source/core/types/ut_executable_test.tps b/source/core/types/ut_executable_test.tps
index 42b6080df..d477456f6 100644
--- a/source/core/types/ut_executable_test.tps
+++ b/source/core/types/ut_executable_test.tps
@@ -1,7 +1,7 @@
-create or replace type ut_executable_test authid current_user under ut_executable (
+create or replace noneditionable type ut_executable_test authid current_user under ut_executable (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -22,12 +22,12 @@ create or replace type ut_executable_test authid current_user under ut_executabl
member procedure do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
- a_expected_error_codes in ut_varchar2_rows
+ a_expected_errors in ut_varchar2_rows
),
member function do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
- a_expected_error_codes in ut_varchar2_rows
+ a_expected_errors in ut_varchar2_rows
) return boolean
) final;
diff --git a/source/core/types/ut_executables.tps b/source/core/types/ut_executables.tps
index d6d52b3d2..7718c44b8 100644
--- a/source/core/types/ut_executables.tps
+++ b/source/core/types/ut_executables.tps
@@ -1,7 +1,7 @@
-create or replace type ut_executables as
+create or replace noneditionable type ut_executables as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_expectation_result.tpb b/source/core/types/ut_expectation_result.tpb
index 0b3adf983..3ffd11789 100644
--- a/source/core/types/ut_expectation_result.tpb
+++ b/source/core/types/ut_expectation_result.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_expectation_result is
+create or replace noneditionable type body ut_expectation_result is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_expectation_result.tps b/source/core/types/ut_expectation_result.tps
index d4b4c7548..e7eedd5ce 100644
--- a/source/core/types/ut_expectation_result.tps
+++ b/source/core/types/ut_expectation_result.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation_result under ut_event_item(
+create or replace noneditionable type ut_expectation_result under ut_event_item(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_expectation_results.tps b/source/core/types/ut_expectation_results.tps
index e5e4c6223..168941112 100644
--- a/source/core/types/ut_expectation_results.tps
+++ b/source/core/types/ut_expectation_results.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation_results as
+create or replace noneditionable type ut_expectation_results as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_file_mapping.tpb b/source/core/types/ut_file_mapping.tpb
index dab1e35c5..d693ac633 100644
--- a/source/core/types/ut_file_mapping.tpb
+++ b/source/core/types/ut_file_mapping.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_file_mapping as
+create or replace noneditionable type body ut_file_mapping as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_file_mapping.tps b/source/core/types/ut_file_mapping.tps
index 941d95283..d28ef40ae 100644
--- a/source/core/types/ut_file_mapping.tps
+++ b/source/core/types/ut_file_mapping.tps
@@ -1,7 +1,7 @@
-create or replace type ut_file_mapping as object(
+create or replace noneditionable type ut_file_mapping as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_file_mappings.tps b/source/core/types/ut_file_mappings.tps
index 240fb8dd7..715530ee0 100644
--- a/source/core/types/ut_file_mappings.tps
+++ b/source/core/types/ut_file_mappings.tps
@@ -1,7 +1,7 @@
-create or replace type ut_file_mappings as
+create or replace noneditionable type ut_file_mappings as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_integer_list.tps b/source/core/types/ut_integer_list.tps
index ec9a2a78f..b15cf743c 100644
--- a/source/core/types/ut_integer_list.tps
+++ b/source/core/types/ut_integer_list.tps
@@ -1,7 +1,7 @@
-create or replace type ut_integer_list as
+create or replace noneditionable type ut_integer_list as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_key_value_pair.tps b/source/core/types/ut_key_value_pair.tps
index 5a337e608..e26fff031 100644
--- a/source/core/types/ut_key_value_pair.tps
+++ b/source/core/types/ut_key_value_pair.tps
@@ -1,7 +1,7 @@
-create or replace type ut_key_value_pair force as object(
+create or replace noneditionable type ut_key_value_pair force as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_key_value_pairs.tps b/source/core/types/ut_key_value_pairs.tps
index 24bdded36..d9e829dc9 100644
--- a/source/core/types/ut_key_value_pairs.tps
+++ b/source/core/types/ut_key_value_pairs.tps
@@ -1,7 +1,7 @@
-create or replace type ut_key_value_pairs as
+create or replace noneditionable type ut_key_value_pairs as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_logical_suite.tpb b/source/core/types/ut_logical_suite.tpb
index 036d40d51..c91320d8a 100644
--- a/source/core/types/ut_logical_suite.tpb
+++ b/source/core/types/ut_logical_suite.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_logical_suite as
+create or replace noneditionable type body ut_logical_suite as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_logical_suite.tps b/source/core/types/ut_logical_suite.tps
index c4f2f699b..245c422a1 100644
--- a/source/core/types/ut_logical_suite.tps
+++ b/source/core/types/ut_logical_suite.tps
@@ -1,7 +1,7 @@
-create or replace type ut_logical_suite force under ut_suite_item (
+create or replace noneditionable type ut_logical_suite force under ut_suite_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_object_name.tpb b/source/core/types/ut_object_name.tpb
index 76acc15bf..67834a9ed 100644
--- a/source/core/types/ut_object_name.tpb
+++ b/source/core/types/ut_object_name.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_object_name as
+create or replace noneditionable type body ut_object_name as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_object_name.tps b/source/core/types/ut_object_name.tps
index 5f8f724c4..7f6341a32 100644
--- a/source/core/types/ut_object_name.tps
+++ b/source/core/types/ut_object_name.tps
@@ -1,7 +1,7 @@
-create or replace type ut_object_name as object (
+create or replace noneditionable type ut_object_name as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_object_names.tps b/source/core/types/ut_object_names.tps
index 03830be17..879493a63 100644
--- a/source/core/types/ut_object_names.tps
+++ b/source/core/types/ut_object_names.tps
@@ -1,7 +1,7 @@
-create or replace type ut_object_names as
+create or replace noneditionable type ut_object_names as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_output_reporter_base.tpb b/source/core/types/ut_output_reporter_base.tpb
index f6bb27b94..4553f1780 100644
--- a/source/core/types/ut_output_reporter_base.tpb
+++ b/source/core/types/ut_output_reporter_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_output_reporter_base is
+create or replace noneditionable type body ut_output_reporter_base is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -41,13 +41,6 @@ create or replace type body ut_output_reporter_base is
return l_result;
end;
- overriding member procedure before_calling_run(self in out nocopy ut_output_reporter_base, a_run in ut_run) is
- l_output_table_buffer ut_output_table_buffer;
- begin
- (self as ut_reporter_base).before_calling_run(a_run);
- l_output_table_buffer := treat(self.output_buffer as ut_output_table_buffer);
- end;
-
member procedure print_text(self in out nocopy ut_output_reporter_base, a_text varchar2, a_item_type varchar2 := null) is
begin
self.output_buffer.send_line(a_text, a_item_type);
@@ -87,6 +80,7 @@ create or replace type body ut_output_reporter_base is
overriding member procedure on_initialize(self in out nocopy ut_output_reporter_base, a_run in ut_run) is
begin
+ self.output_buffer.lock_buffer();
self.output_buffer.send_line(null, 'initialize');
end;
diff --git a/source/core/types/ut_output_reporter_base.tps b/source/core/types/ut_output_reporter_base.tps
index 22f507f8d..b9ec4f7cd 100644
--- a/source/core/types/ut_output_reporter_base.tps
+++ b/source/core/types/ut_output_reporter_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_reporter_base under ut_reporter_base(
+create or replace noneditionable type ut_output_reporter_base under ut_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -20,8 +20,7 @@ create or replace type ut_output_reporter_base under ut_reporter_base(
member procedure init(self in out nocopy ut_output_reporter_base, a_self_type varchar2, a_output_buffer ut_output_buffer_base := null),
overriding member procedure set_reporter_id(self in out nocopy ut_output_reporter_base, a_reporter_id raw),
member function set_reporter_id(self in ut_output_reporter_base, a_reporter_id raw) return ut_output_reporter_base,
- overriding member procedure before_calling_run(self in out nocopy ut_output_reporter_base, a_run in ut_run),
-
+
member procedure print_text(self in out nocopy ut_output_reporter_base, a_text varchar2, a_item_type varchar2 := null),
member procedure print_text_lines(self in out nocopy ut_output_reporter_base, a_text_lines ut_varchar2_rows, a_item_type varchar2 := null),
member procedure print_clob(self in out nocopy ut_output_reporter_base, a_clob clob, a_item_type varchar2 := null),
diff --git a/source/core/types/ut_path_item.tpb b/source/core/types/ut_path_item.tpb
index 6cdb2b8ad..486fde865 100644
--- a/source/core/types/ut_path_item.tpb
+++ b/source/core/types/ut_path_item.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_path_item as
+create or replace noneditionable type body ut_path_item as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_path_item.tps b/source/core/types/ut_path_item.tps
index c8ec81be5..fdc1e8ac2 100644
--- a/source/core/types/ut_path_item.tps
+++ b/source/core/types/ut_path_item.tps
@@ -1,7 +1,7 @@
-create or replace type ut_path_item as object (
+create or replace noneditionable type ut_path_item as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_path_items.tps b/source/core/types/ut_path_items.tps
index 0c87cf28c..64f8dd5fe 100644
--- a/source/core/types/ut_path_items.tps
+++ b/source/core/types/ut_path_items.tps
@@ -1,7 +1,7 @@
-create or replace type ut_path_items as
+create or replace noneditionable type ut_path_items as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_reporter_base.tpb b/source/core/types/ut_reporter_base.tpb
index 3f8984331..e457645f4 100644
--- a/source/core/types/ut_reporter_base.tpb
+++ b/source/core/types/ut_reporter_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_reporter_base is
+create or replace noneditionable type body ut_reporter_base is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -165,52 +165,54 @@ create or replace type body ut_reporter_base is
end;
overriding member procedure on_event( self in out nocopy ut_reporter_base, a_event_name varchar2, a_event_item ut_event_item) is
+ /* Resolves issue with ORA-21779 being thrown see issue: 1309 -> ( https://github.com/utPLSQL/utPLSQL/issues/1309#issuecomment-4020289898 ) */
+ l_event_item ut_event_item := a_event_item;
begin
case a_event_name
when ut_event_manager.gc_initialize
- then self.on_initialize(treat(a_event_item as ut_run));
+ then self.on_initialize(treat(l_event_item as ut_run));
when ut_event_manager.gc_before_run
- then self.before_calling_run(treat(a_event_item as ut_run));
+ then self.before_calling_run(treat(l_event_item as ut_run));
when ut_event_manager.gc_before_suite
- then self.before_calling_suite(treat(a_event_item as ut_logical_suite));
+ then self.before_calling_suite(treat(l_event_item as ut_logical_suite));
when ut_event_manager.gc_before_before_all
- then self.before_calling_before_all(treat(a_event_item as ut_executable));
+ then self.before_calling_before_all(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_before_each
- then self.before_calling_before_each(treat(a_event_item as ut_executable));
+ then self.before_calling_before_each(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_test
- then self.before_calling_test(treat(a_event_item as ut_test));
+ then self.before_calling_test(treat(l_event_item as ut_test));
when ut_event_manager.gc_before_before_test
- then self.before_calling_before_test(treat(a_event_item as ut_executable));
+ then self.before_calling_before_test(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_test_execute
- then self.before_calling_test_execute(treat(a_event_item as ut_executable));
+ then self.before_calling_test_execute(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_after_test
- then self.before_calling_after_test(treat(a_event_item as ut_executable));
+ then self.before_calling_after_test(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_after_each
- then self.before_calling_after_each(treat(a_event_item as ut_executable));
+ then self.before_calling_after_each(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_after_all
- then self.before_calling_after_all(treat(a_event_item as ut_executable));
+ then self.before_calling_after_all(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_run
- then self.after_calling_run(treat(a_event_item as ut_run));
+ then self.after_calling_run(treat(l_event_item as ut_run));
when ut_event_manager.gc_after_suite
- then self.after_calling_suite(treat(a_event_item as ut_logical_suite));
+ then self.after_calling_suite(treat(l_event_item as ut_logical_suite));
when ut_event_manager.gc_after_before_all
- then self.after_calling_before_all(treat(a_event_item as ut_executable));
+ then self.after_calling_before_all(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_before_each
- then self.after_calling_before_each(treat(a_event_item as ut_executable));
+ then self.after_calling_before_each(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_test
- then self.after_calling_test(treat(a_event_item as ut_test));
+ then self.after_calling_test(treat(l_event_item as ut_test));
when ut_event_manager.gc_after_before_test
- then self.after_calling_before_test(treat(a_event_item as ut_executable));
+ then self.after_calling_before_test(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_test_execute
- then self.after_calling_test_execute(treat(a_event_item as ut_executable));
+ then self.after_calling_test_execute(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_after_test
- then self.after_calling_after_test(treat(a_event_item as ut_executable));
+ then self.after_calling_after_test(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_after_each
- then self.after_calling_after_each(treat(a_event_item as ut_executable));
+ then self.after_calling_after_each(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_after_all
- then self.after_calling_after_all(treat(a_event_item as ut_executable));
+ then self.after_calling_after_all(treat(l_event_item as ut_executable));
when ut_event_manager.gc_finalize
- then self.on_finalize(treat(a_event_item as ut_run));
+ then self.on_finalize(treat(l_event_item as ut_run));
else null;
end case;
end;
diff --git a/source/core/types/ut_reporter_base.tps b/source/core/types/ut_reporter_base.tps
index de157136e..af0472dc5 100644
--- a/source/core/types/ut_reporter_base.tps
+++ b/source/core/types/ut_reporter_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_reporter_base under ut_event_listener (
+create or replace noneditionable type ut_reporter_base under ut_event_listener (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_reporter_info.tps b/source/core/types/ut_reporter_info.tps
index f09c42e07..29c7559f1 100644
--- a/source/core/types/ut_reporter_info.tps
+++ b/source/core/types/ut_reporter_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_reporter_info as object (
+create or replace noneditionable type ut_reporter_info as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_reporters.tps b/source/core/types/ut_reporters.tps
index a2802bb26..fba22480f 100644
--- a/source/core/types/ut_reporters.tps
+++ b/source/core/types/ut_reporters.tps
@@ -1,7 +1,7 @@
-create or replace type ut_reporters as
+create or replace noneditionable type ut_reporters as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_reporters_info.tps b/source/core/types/ut_reporters_info.tps
index 82c264f36..4f6f054a3 100644
--- a/source/core/types/ut_reporters_info.tps
+++ b/source/core/types/ut_reporters_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_reporters_info as
+create or replace noneditionable type ut_reporters_info as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_results_counter.tpb b/source/core/types/ut_results_counter.tpb
index 811389e0e..54f9e0b48 100644
--- a/source/core/types/ut_results_counter.tpb
+++ b/source/core/types/ut_results_counter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_results_counter as
+create or replace noneditionable type body ut_results_counter as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_results_counter.tps b/source/core/types/ut_results_counter.tps
index 913ae0967..477d4b217 100644
--- a/source/core/types/ut_results_counter.tps
+++ b/source/core/types/ut_results_counter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_results_counter as object(
+create or replace noneditionable type ut_results_counter as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_run.tpb b/source/core/types/ut_run.tpb
index cdafb30fc..80621b5ad 100644
--- a/source/core/types/ut_run.tpb
+++ b/source/core/types/ut_run.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_run as
+create or replace noneditionable type body ut_run as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ create or replace type body ut_run as
a_test_file_mappings ut_file_mappings := null,
a_client_character_set varchar2 := null,
a_random_test_order_seed positive := null,
- a_run_tags ut_varchar2_rows := null
+ a_run_tags varchar2 := null
) return self as result is
begin
self.run_paths := a_run_paths;
diff --git a/source/core/types/ut_run.tps b/source/core/types/ut_run.tps
index debf847cd..551e56ac4 100644
--- a/source/core/types/ut_run.tps
+++ b/source/core/types/ut_run.tps
@@ -1,7 +1,7 @@
-create or replace type ut_run under ut_suite_item (
+create or replace noneditionable type ut_run under ut_suite_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ create or replace type ut_run under ut_suite_item (
project_name varchar2(4000),
items ut_suite_items,
run_paths ut_varchar2_list,
- run_tags ut_varchar2_rows,
+ run_tags varchar2(4000),
coverage_options ut_coverage_options,
test_file_mappings ut_file_mappings,
client_character_set varchar2(100),
@@ -34,7 +34,7 @@ create or replace type ut_run under ut_suite_item (
a_test_file_mappings ut_file_mappings := null,
a_client_character_set varchar2 := null,
a_random_test_order_seed positive := null,
- a_run_tags ut_varchar2_rows := null
+ a_run_tags varchar2 := null
) return self as result,
overriding member procedure mark_as_skipped(self in out nocopy ut_run,a_skip_reason in varchar2),
overriding member function do_execute(self in out nocopy ut_run) return boolean,
diff --git a/source/core/types/ut_run_info.tpb b/source/core/types/ut_run_info.tpb
index 6edc0f109..3de74b2b4 100644
--- a/source/core/types/ut_run_info.tpb
+++ b/source/core/types/ut_run_info.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_run_info as
+create or replace noneditionable type body ut_run_info as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_run_info.tps b/source/core/types/ut_run_info.tps
index 4a3da691f..00919b172 100644
--- a/source/core/types/ut_run_info.tps
+++ b/source/core/types/ut_run_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_run_info under ut_event_item (
+create or replace noneditionable type ut_run_info under ut_event_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_stack.tpb b/source/core/types/ut_stack.tpb
new file mode 100644
index 000000000..4298ae35c
--- /dev/null
+++ b/source/core/types/ut_stack.tpb
@@ -0,0 +1,58 @@
+create or replace noneditionable type body ut_stack as
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+ constructor function ut_stack( self in out nocopy ut_stack) return self as result is
+ begin
+ self.tokens := ut_varchar2_list();
+ self.top := 0;
+ return;
+ end ut_stack;
+
+ member function peek(self in out nocopy ut_stack) return varchar2 is
+ l_token varchar2(32767);
+ begin
+ if self.tokens.count =0 or self.tokens is null then
+ l_token := null;
+ else
+ l_token := self.tokens(self.tokens.last);
+ end if;
+ return l_token;
+ end;
+
+ member procedure push(self in out nocopy ut_stack, a_token varchar2) is
+ begin
+ self.tokens.extend;
+ self.tokens(self.tokens.last) := a_token;
+ self.top := self.tokens.count;
+ end push;
+
+ member procedure pop(self in out nocopy ut_stack,a_cnt in integer default 1) is
+ begin
+ self.tokens.trim(a_cnt);
+ self.top := self.tokens.count;
+ end pop;
+
+ member function pop(self in out nocopy ut_stack) return varchar2 is
+ l_token varchar2(32767) := self.tokens(self.tokens.last);
+ begin
+ self.pop();
+ return l_token;
+ end;
+end;
+/
+
diff --git a/source/reporters/ut_coveralls_reporter.tps b/source/core/types/ut_stack.tps
similarity index 51%
rename from source/reporters/ut_coveralls_reporter.tps
rename to source/core/types/ut_stack.tps
index 74363b751..ed79bea55 100644
--- a/source/reporters/ut_coveralls_reporter.tps
+++ b/source/core/types/ut_stack.tps
@@ -1,7 +1,9 @@
-create or replace type ut_coveralls_reporter under ut_coverage_reporter_base(
+create or replace noneditionable type ut_stack as object (
+ top integer,
+ tokens ut_varchar2_list,
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -15,17 +17,10 @@ create or replace type ut_coveralls_reporter under ut_coverage_reporter_base(
See the License for the specific language governing permissions and
limitations under the License.
*/
-
- /**
- * Builds a coverage XML report that follows rules described in
- * https://docs.coveralls.io/api-introduction
- */
- constructor function ut_coveralls_reporter(
- self in out nocopy ut_coveralls_reporter
- ) return self as result,
-
- overriding member procedure after_calling_run(self in out nocopy ut_coveralls_reporter, a_run in ut_run),
-
- overriding member function get_description return varchar2
+ constructor function ut_stack( self in out nocopy ut_stack) return self as result,
+ member function peek(self in out nocopy ut_stack) return varchar2,
+ member procedure push(self in out nocopy ut_stack, a_token varchar2),
+ member procedure pop(self in out nocopy ut_stack,a_cnt in integer default 1),
+ member function pop(self in out nocopy ut_stack) return varchar2
)
-/
+/
\ No newline at end of file
diff --git a/source/core/types/ut_suite.tpb b/source/core/types/ut_suite.tpb
index e3a4687d8..b4e3eabf0 100644
--- a/source/core/types/ut_suite.tpb
+++ b/source/core/types/ut_suite.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_suite as
+create or replace noneditionable type body ut_suite as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite.tps b/source/core/types/ut_suite.tps
index ff7f3e171..edce778f1 100644
--- a/source/core/types/ut_suite.tps
+++ b/source/core/types/ut_suite.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite under ut_logical_suite (
+create or replace noneditionable type ut_suite under ut_logical_suite (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_cache_row.tps b/source/core/types/ut_suite_cache_row.tps
index c147a8757..1ee371a88 100644
--- a/source/core/types/ut_suite_cache_row.tps
+++ b/source/core/types/ut_suite_cache_row.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_cache_row as object (
+create or replace noneditionable type ut_suite_cache_row as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_cache_rows.tps b/source/core/types/ut_suite_cache_rows.tps
index 9b6919df5..84bcc9f75 100644
--- a/source/core/types/ut_suite_cache_rows.tps
+++ b/source/core/types/ut_suite_cache_rows.tps
@@ -1,7 +1,7 @@
-create type ut_suite_cache_rows as
+create or replace noneditionable type ut_suite_cache_rows as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_context.tpb b/source/core/types/ut_suite_context.tpb
index be92e6fc9..dad24e42e 100644
--- a/source/core/types/ut_suite_context.tpb
+++ b/source/core/types/ut_suite_context.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_suite_context as
+create or replace noneditionable type body ut_suite_context as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_context.tps b/source/core/types/ut_suite_context.tps
index 5e3d20f87..b890e2633 100644
--- a/source/core/types/ut_suite_context.tps
+++ b/source/core/types/ut_suite_context.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_context under ut_suite (
+create or replace noneditionable type ut_suite_context under ut_suite (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_item.tpb b/source/core/types/ut_suite_item.tpb
index 648f10dd1..8e8c6fd90 100644
--- a/source/core/types/ut_suite_item.tpb
+++ b/source/core/types/ut_suite_item.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_suite_item as
+create or replace noneditionable type body ut_suite_item as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_item.tps b/source/core/types/ut_suite_item.tps
index 8184f2a63..2e990353f 100644
--- a/source/core/types/ut_suite_item.tps
+++ b/source/core/types/ut_suite_item.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_item force under ut_event_item (
+create or replace noneditionable type ut_suite_item force under ut_event_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_items.tps b/source/core/types/ut_suite_items.tps
index 615283446..b7ce9873c 100644
--- a/source/core/types/ut_suite_items.tps
+++ b/source/core/types/ut_suite_items.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_items as
+create or replace noneditionable type ut_suite_items as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_test.tpb b/source/core/types/ut_test.tpb
index 946f8990d..61a1e39f8 100644
--- a/source/core/types/ut_test.tpb
+++ b/source/core/types/ut_test.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_test as
+create or replace noneditionable type body ut_test as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_test.tps b/source/core/types/ut_test.tps
index dbba64961..cb50c2fd4 100644
--- a/source/core/types/ut_test.tps
+++ b/source/core/types/ut_test.tps
@@ -1,7 +1,7 @@
-create or replace type ut_test force under ut_suite_item (
+create or replace noneditionable type ut_test force under ut_suite_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_varchar2_list.tps b/source/core/types/ut_varchar2_list.tps
index f0b5df509..8203a4bab 100644
--- a/source/core/types/ut_varchar2_list.tps
+++ b/source/core/types/ut_varchar2_list.tps
@@ -1,7 +1,7 @@
-create or replace type ut_varchar2_list as
+create or replace noneditionable type ut_varchar2_list as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_varchar2_rows.tps b/source/core/types/ut_varchar2_rows.tps
index e7fa29c29..a2e25e9fb 100644
--- a/source/core/types/ut_varchar2_rows.tps
+++ b/source/core/types/ut_varchar2_rows.tps
@@ -1,7 +1,7 @@
-create or replace type ut_varchar2_rows as
+create or replace noneditionable type ut_varchar2_rows as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_dbms_output_cache.sql b/source/core/ut_dbms_output_cache.sql
index e61b403c8..802f30942 100644
--- a/source/core/ut_dbms_output_cache.sql
+++ b/source/core/ut_dbms_output_cache.sql
@@ -1,15 +1,16 @@
/*
-utPLSQL - Version 3
-Copyright 2016 - 2021 utPLSQL Project
-Licensed under the Apache License, Version 2.0 (the "License"):
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
*/
/*
* This table is not a global temporary table as it needs to allow cross-session data exchange
diff --git a/source/core/ut_expectation_processor.pkb b/source/core/ut_expectation_processor.pkb
index 77b734b30..3fb39a5b9 100644
--- a/source/core/ut_expectation_processor.pkb
+++ b/source/core/ut_expectation_processor.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_expectation_processor as
+create or replace noneditionable package body ut_expectation_processor as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -159,17 +159,17 @@ create or replace package body ut_expectation_processor as
-- when 11g and 12c reports only package name
function cut_header_and_expectations( a_stack varchar2 ) return varchar2 is
begin
- return regexp_substr( a_stack, '(.*\.(UT_EQUAL|UT_BE_WITHIN[A-Z0-9#_$]*|UT_EXPECTATION[A-Z0-9#_$]*|UT|UTASSERT2?)(\.[A-Z0-9#_$]+)?\s+)+((.|\s)*)', 1, 1, 'm', 4);
+ return regexp_substr( a_stack, '(.*\.(UT_EQUAL|UT_BE_WITHIN[[:alnum:]$#_]*|UT_EXPECTATION[[:alnum:]$#_]*|UT|UTASSERT2?)(\.[[:alnum:]$#_]+)?\s+)+((.|\s)*)', 1, 1, 'm', 4);
end;
function cut_address_columns( a_stack varchar2 ) return varchar2 is
begin
- return regexp_replace( a_stack, '^(0x)?[0-9a-f]+\s+', '', 1, 0, 'mi' );
+ return regexp_replace( a_stack, '^(0x)?[[:digit:]abcdef]+\s+', '', 1, 0, 'mi' );
end;
function cut_framework_stack( a_stack varchar2 ) return varchar2 is
begin
return regexp_replace(
a_stack,
- '[0-9]+\s+anonymous\s+block\s+[0-9]+\s+package\s+body\s+sys\.dbms_sql(\.execute)?\s+[0-9]+\s+[0-9_$#a-z ]+\.ut_executable.*',
+ '[0-9]+\s+anonymous\s+block\s+[0-9]+\s+package\s+body\s+sys\.dbms_sql(\.execute)?\s+[0-9]+\s+[[:alnum:]_$# ]+\.ut_executable.*',
'',
1, 1, 'mni'
);
@@ -178,7 +178,7 @@ create or replace package body ut_expectation_processor as
begin
return regexp_replace(
a_stack,
- '([0-9]+)\s+(.* )?((anonymous block)|(([0-9_$#a-z]+\.[0-9_$#a-z]+(\.([0-9_$#a-z])+)?)))',
+ '([0-9]+)\s+(.* )?((anonymous block)|(([[:alnum:]$#_]+\.[[:alnum:]$#_]+(\.([[:alnum:]$#_])+)?)))',
'at "\3", line \1', 1, 0, 'i'
);
end;
@@ -190,8 +190,8 @@ create or replace package body ut_expectation_processor as
l_caller_stack_line := regexp_substr(l_call_stack,'^(.*)');
if l_caller_stack_line like '%.%' then
l_line_no := to_number( regexp_substr( l_caller_stack_line, ', line (\d+)', subexpression => 1 ) );
- l_owner := regexp_substr( l_caller_stack_line, 'at "([A-Za-z0-9$#_]+)\.(([A-Za-z0-9$#_]+)(\.([A-Za-z0-9$#_]+))?)", line (\d+)', subexpression => 1 );
- l_object_name := regexp_substr( l_caller_stack_line, 'at "([A-Za-z0-9$#_]+)\.(([A-Za-z0-9$#_]+)(\.([A-Za-z0-9$#_]+))?)", line (\d+)', subexpression => 3 );
+ l_owner := regexp_substr( l_caller_stack_line, 'at "([[:alnum:]$#_]+)\.(([[:alnum:]$#_]+)(\.([[:alnum:]$#_]+))?)", line (\d+)', subexpression => 1 );
+ l_object_name := regexp_substr( l_caller_stack_line, 'at "([[:alnum:]$#_]+)\.(([[:alnum:]$#_]+)(\.([[:alnum:]$#_]+))?)", line (\d+)', subexpression => 3 );
l_result :=
l_caller_stack_line || ' ' || rtrim(ut_metadata.get_source_definition_line(l_owner, l_object_name, l_line_no),chr(10))
|| replace( l_call_stack, l_caller_stack_line );
diff --git a/source/core/ut_expectation_processor.pks b/source/core/ut_expectation_processor.pks
index dd9187526..5349ee70a 100644
--- a/source/core/ut_expectation_processor.pks
+++ b/source/core/ut_expectation_processor.pks
@@ -1,7 +1,7 @@
-create or replace package ut_expectation_processor authid current_user as
+create or replace noneditionable package ut_expectation_processor authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_file_mapper.pkb b/source/core/ut_file_mapper.pkb
index 425360533..40204a5da 100644
--- a/source/core/ut_file_mapper.pkb
+++ b/source/core/ut_file_mapper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_file_mapper is
+create or replace noneditionable package body ut_file_mapper is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_file_mapper.pks b/source/core/ut_file_mapper.pks
index adc4c983f..1363e81ec 100644
--- a/source/core/ut_file_mapper.pks
+++ b/source/core/ut_file_mapper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_file_mapper authid current_user is
+create or replace noneditionable package ut_file_mapper authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_metadata.pkb b/source/core/ut_metadata.pkb
index 700c0efb0..d9939ad45 100644
--- a/source/core/ut_metadata.pkb
+++ b/source/core/ut_metadata.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_metadata as
+create or replace noneditionable package body ut_metadata as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -304,7 +304,7 @@ create or replace package body ut_metadata as
begin
l_result := regexp_substr(
a_full_object_name,
- '^([A-Za-z0-9$#_]+|".*?")\.([A-Za-z0-9$#_]+|".*?")', subexpression => 2
+ '^([[:alnum:]$#_]+|".*?")\.([[:alnum:]$#_]+|".*?")', subexpression => 2
);
if not l_result like '"%"' then
l_result := upper(l_result);
diff --git a/source/core/ut_metadata.pks b/source/core/ut_metadata.pks
index 27bfa5d30..42f136504 100644
--- a/source/core/ut_metadata.pks
+++ b/source/core/ut_metadata.pks
@@ -1,7 +1,7 @@
-create or replace package ut_metadata authid current_user as
+create or replace noneditionable package ut_metadata authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_savepoint_seq.sql b/source/core/ut_savepoint_seq.sql
index 5b0cda35e..2026ab0e3 100644
--- a/source/core/ut_savepoint_seq.sql
+++ b/source/core/ut_savepoint_seq.sql
@@ -1,7 +1,7 @@
create sequence ut_savepoint_seq
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb
index ebb113370..4f0e28606 100644
--- a/source/core/ut_suite_builder.pkb
+++ b/source/core/ut_suite_builder.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_suite_builder is
+create or replace noneditionable package body ut_suite_builder is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -754,7 +754,7 @@ create or replace package body ut_suite_builder is
l_used_context_names(l_context_name) := true;
l_context := ut_suite_context(a_parent.object_owner, a_parent.object_name, l_context_name, l_context_pos );
- l_context.path := a_parent.path||'.'||l_context_name;
+ l_context.path := a_parent.path||'.'||l_context.name;
l_context.description := coalesce( a_annotations.by_line( l_context_pos ).text, l_context_name );
l_context.parse_time := a_annotations.parse_time;
diff --git a/source/core/ut_suite_builder.pks b/source/core/ut_suite_builder.pks
index 352601a6d..35f207ea4 100644
--- a/source/core/ut_suite_builder.pks
+++ b/source/core/ut_suite_builder.pks
@@ -1,7 +1,7 @@
-create or replace package ut_suite_builder authid current_user is
+create or replace noneditionable package ut_suite_builder authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_suite_cache.sql b/source/core/ut_suite_cache.sql
index 182caabd0..1d7389e9f 100644
--- a/source/core/ut_suite_cache.sql
+++ b/source/core/ut_suite_cache.sql
@@ -1,7 +1,7 @@
create table ut_suite_cache
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/ut_suite_cache_manager.pkb b/source/core/ut_suite_cache_manager.pkb
index d3e832a9b..9aa3cf63d 100644
--- a/source/core/ut_suite_cache_manager.pkb
+++ b/source/core/ut_suite_cache_manager.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_suite_cache_manager is
+create or replace noneditionable package body ut_suite_cache_manager is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -88,7 +88,7 @@ create or replace package body ut_suite_cache_manager is
end;
function group_paths_by_schema(a_paths ut_varchar2_list) return ut_path_items is
- c_package_path_regex constant varchar2(100) := '^([A-Za-z0-9$#_]+)(\.([A-Za-z0-9$#_\*]+))?(\.([A-Za-z0-9$#_\*]+))?$';
+ c_package_path_regex constant varchar2(100) := '^([[:alnum:]$#_]+)(\.([[:alnum:]$#_\*]+))?(\.([[:alnum:]$#_\*]+))?$';
l_results ut_path_items := ut_path_items();
l_path_item ut_path_item;
i pls_integer;
@@ -157,7 +157,7 @@ create or replace package body ut_suite_cache_manager is
from schema_paths sp left outer join ut_suite_cache c on
( c.object_owner = upper(sp.schema_name)
--and c.path like replace(sp.suite_path,'*','%'))
- and regexp_like(c.path,'^'||replace(sp.suite_path,'*','[A-Za-z0-9$#_]*')))
+ and regexp_like(c.path,'^'||replace(sp.suite_path,'*','[[:alnum:]$#_]*')))
where sp.suite_path is not null and instr(sp.suite_path,'*') > 0
),
straigth_suite_paths as (
@@ -220,55 +220,7 @@ create or replace package body ut_suite_cache_manager is
and c.name = nvl(upper(sp.procedure_name),c.name)))) where r_num =1;
return l_suite_items;
end;
-
- /*
- Having a base set of suites we will do a further filter down if there are
- any tags defined.
- */
- function get_tags_suites (
- a_suite_items ut_suite_cache_rows,
- a_tags ut_varchar2_rows
- ) return ut_suite_cache_rows is
- l_suite_tags ut_suite_cache_rows := ut_suite_cache_rows();
- l_include_tags ut_varchar2_rows;
- l_exclude_tags ut_varchar2_rows;
- begin
-
- select /*+ no_parallel */ column_value
- bulk collect into l_include_tags
- from table(a_tags)
- where column_value not like '-%';
-
- select /*+ no_parallel */ ltrim(column_value,'-')
- bulk collect into l_exclude_tags
- from table(a_tags)
- where column_value like '-%';
-
- with included_tags as (
- select c.path as path
- from table(a_suite_items) c
- where c.tags multiset intersect l_include_tags is not empty or l_include_tags is empty
- ),
- excluded_tags as (
- select c.path as path
- from table(a_suite_items) c
- where c.tags multiset intersect l_exclude_tags is not empty
- )
- select value(c) as obj
- bulk collect into l_suite_tags
- from table(a_suite_items) c
- where exists (
- select 1 from included_tags t
- where t.path||'.' like c.path || '.%' /*all ancestors and self*/
- or c.path||'.' like t.path || '.%' /*all descendants and self*/
- )
- and not exists (
- select 1 from excluded_tags t
- where c.path||'.' like t.path || '.%' /*all descendants and self*/
- );
- return l_suite_tags;
- end;
-
+
/*
We will sort a suites in hierarchical structure.
Sorting from bottom to top so when we consolidate
@@ -321,31 +273,18 @@ create or replace package body ut_suite_cache_manager is
end;
function get_cached_suite_rows(
- a_schema_paths ut_path_items,
- a_random_seed positive := null,
- a_tags ut_varchar2_rows := null
+ a_suites_filtered ut_suite_cache_rows
) return ut_suite_cache_rows is
l_results ut_suite_cache_rows := ut_suite_cache_rows();
- l_suite_items ut_suite_cache_rows := ut_suite_cache_rows();
- l_schema_paths ut_path_items;
- l_tags ut_varchar2_rows := coalesce(a_tags,ut_varchar2_rows());
begin
- l_schema_paths := a_schema_paths;
- l_suite_items := get_suite_items(a_schema_paths);
- if l_tags.count > 0 then
- l_suite_items := get_tags_suites(l_suite_items,l_tags);
- end if;
-
- open c_get_bulk_cache_suite(l_suite_items);
+ open c_get_bulk_cache_suite(a_suites_filtered);
fetch c_get_bulk_cache_suite bulk collect into l_results;
close c_get_bulk_cache_suite;
return l_results;
end;
-
-
function get_schema_parse_time(a_schema_name varchar2) return timestamp result_cache is
l_cache_parse_time timestamp;
begin
@@ -367,7 +306,7 @@ create or replace package body ut_suite_cache_manager is
l_object_owner varchar2(250) := upper(a_object_owner);
l_object_name varchar2(250) := upper(a_object_name);
begin
- if a_suite_items is not null and a_suite_items.count = 0 then
+ if a_suite_items is null or a_suite_items.count = 0 then
delete from ut_suite_cache t
where t.object_owner = l_object_owner
@@ -492,7 +431,7 @@ create or replace package body ut_suite_cache_manager is
a_schema_paths ut_path_items
) return ut_suite_cache_rows is
begin
- return get_cached_suite_rows( a_schema_paths );
+ return get_cached_suite_rows(get_suite_items(a_schema_paths));
end;
function get_suite_items_info(
diff --git a/source/core/ut_suite_cache_manager.pks b/source/core/ut_suite_cache_manager.pks
index 974babca5..6ac1d7bd6 100644
--- a/source/core/ut_suite_cache_manager.pks
+++ b/source/core/ut_suite_cache_manager.pks
@@ -1,7 +1,7 @@
-create or replace package ut_suite_cache_manager authid definer is
+create or replace noneditionable package ut_suite_cache_manager authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -55,11 +55,9 @@ create or replace package ut_suite_cache_manager authid definer is
* Not to be used publicly. Used internally for building suites at runtime.
*/
function get_cached_suite_rows(
- a_schema_paths ut_path_items,
- a_random_seed positive := null,
- a_tags ut_varchar2_rows := null
+ a_suites_filtered ut_suite_cache_rows
) return ut_suite_cache_rows;
-
+
function get_schema_paths(a_paths in ut_varchar2_list) return ut_path_items;
/*
@@ -74,6 +72,10 @@ create or replace package ut_suite_cache_manager authid definer is
function get_suite_items_info(
a_suite_cache_items ut_suite_cache_rows
) return ut_suite_items_info;
+
+ function get_suite_items (
+ a_schema_paths ut_path_items
+ ) return ut_suite_cache_rows;
/*
* Retrieves list of cached suite packages.
@@ -94,6 +96,6 @@ create or replace package ut_suite_cache_manager authid definer is
a_package_name varchar2,
a_procedure_name varchar2
) return boolean;
-
+
end ut_suite_cache_manager;
/
diff --git a/source/core/ut_suite_cache_package.sql b/source/core/ut_suite_cache_package.sql
index 7a146ff83..40b7b8dec 100644
--- a/source/core/ut_suite_cache_package.sql
+++ b/source/core/ut_suite_cache_package.sql
@@ -1,7 +1,7 @@
create table ut_suite_cache_package (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/ut_suite_cache_schema.sql b/source/core/ut_suite_cache_schema.sql
index 636816e65..cace332e3 100644
--- a/source/core/ut_suite_cache_schema.sql
+++ b/source/core/ut_suite_cache_schema.sql
@@ -1,7 +1,7 @@
create table ut_suite_cache_schema (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/ut_suite_cache_seq.sql b/source/core/ut_suite_cache_seq.sql
index e1e560286..020c25c4d 100644
--- a/source/core/ut_suite_cache_seq.sql
+++ b/source/core/ut_suite_cache_seq.sql
@@ -1,7 +1,7 @@
create sequence ut_suite_cache_seq
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb
index 805fd608b..fa60be59e 100644
--- a/source/core/ut_suite_manager.pkb
+++ b/source/core/ut_suite_manager.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_suite_manager is
+create or replace noneditionable package body ut_suite_manager is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@ create or replace package body ut_suite_manager is
for i in 1 .. a_paths.count loop
l_path := a_paths(i);
if l_path is null or not (
- regexp_like(l_path, '^[A-Za-z0-9$#_\*]+(\.[A-Za-z0-9$#_\*]+){0,2}$') or regexp_like(l_path, '^([A-Za-z0-9$#_]+)?:[A-Za-z0-9$#_\*]+(\.[A-Za-z0-9$#_\*]+)*$')) then
+ regexp_like(l_path, '^[[:alnum:]$#_\*]+(\.[[:alnum:]$#_\*]+){0,2}$') or regexp_like(l_path, '^([[:alnum:]$#_]+)?:[[:alnum:]$#_\*]+(\.[[:alnum:]$#_\*]+)*$')) then
raise_application_error(ut_utils.gc_invalid_path_format, 'Invalid path format: ' || nvl(l_path, 'NULL'));
end if;
end loop;
@@ -61,9 +61,9 @@ create or replace package body ut_suite_manager is
for i in 1 .. a_paths.count loop
--if path is suite-path
- if regexp_like(a_paths(i), '^([A-Za-z0-9$#_]+)?:') then
+ if regexp_like(a_paths(i), '^([[:alnum:]$#_]+)?:') then
--get schema name / path
- l_schema := regexp_substr(a_paths(i), '^([A-Za-z0-9$#_]+)?:',subexpression => 1);
+ l_schema := regexp_substr(a_paths(i), '^([[:alnum:]$#_]+)?:',subexpression => 1);
-- transform ":path1[.path2]" to "schema:path1[.path2]"
if l_schema is not null then
l_schema := sys.dbms_assert.schema_name(upper(l_schema));
@@ -78,7 +78,7 @@ create or replace package body ut_suite_manager is
-- Object name or procedure is allowed to have filter char
-- However this is not allowed on schema
begin
- l_object := regexp_substr(a_paths(i), '^[A-Za-z0-9$#_\*]+');
+ l_object := regexp_substr(a_paths(i), '^[[:alnum:]$#_\*]+');
l_schema := sys.dbms_assert.schema_name(upper(l_object));
exception
when sys.dbms_assert.invalid_schema_name then
@@ -352,20 +352,18 @@ create or replace package body ut_suite_manager is
function get_cached_suite_data(
a_schema_paths ut_path_items,
a_random_seed positive,
- a_tags ut_varchar2_rows := null,
+ a_tags varchar2 := null,
a_skip_all_objects boolean := false
) return t_cached_suites_cursor is
- l_unfiltered_rows ut_suite_cache_rows;
- l_filtered_rows ut_suite_cache_rows;
- l_result t_cached_suites_cursor;
+ l_unfiltered_rows ut_suite_cache_rows;
+ l_tag_filter_applied ut_suite_cache_rows;
+ l_filtered_rows ut_suite_cache_rows;
+ l_result t_cached_suites_cursor;
begin
- l_unfiltered_rows := ut_suite_cache_manager.get_cached_suite_rows(
- a_schema_paths,
- a_random_seed,
- a_tags
- );
+ l_unfiltered_rows := ut_suite_cache_manager.get_suite_items(a_schema_paths);
- l_filtered_rows := get_filtered_cursor(l_unfiltered_rows,a_skip_all_objects);
+ l_tag_filter_applied := ut_suite_tag_filter.apply(l_unfiltered_rows,a_tags);
+ l_filtered_rows := get_filtered_cursor(ut_suite_cache_manager.get_cached_suite_rows(l_tag_filter_applied),a_skip_all_objects);
reconcile_paths_and_suites(a_schema_paths,l_filtered_rows);
ut_suite_cache_manager.sort_and_randomize_tests(l_filtered_rows,a_random_seed);
@@ -451,7 +449,7 @@ create or replace package body ut_suite_manager is
a_schema_paths ut_path_items,
a_suites in out nocopy ut_suite_items,
a_random_seed positive,
- a_tags ut_varchar2_rows := null
+ a_tags varchar2 := null
) is
begin
reconstruct_from_cache(
@@ -493,13 +491,21 @@ create or replace package body ut_suite_manager is
return l_suites;
end;
- function get_schema_ut_packages(a_schema_names ut_varchar2_rows) return ut_object_names is
+ function get_schema_ut_packages(a_schema_names ut_varchar2_rows, a_schema_name_expr varchar2) return ut_object_names is
+ l_schema_names ut_varchar2_rows := a_schema_names;
begin
- for i in 1 .. a_schema_names.count loop
- refresh_cache(a_schema_names(i));
+ if a_schema_name_expr is not null then
+ select username
+ bulk collect into l_schema_names
+ from all_users
+ where regexp_like(username,a_schema_name_expr,'i');
+ end if;
+
+ for i in 1 .. l_schema_names.count loop
+ refresh_cache(l_schema_names(i));
end loop;
- return ut_suite_cache_manager.get_cached_packages( a_schema_names );
+ return ut_suite_cache_manager.get_cached_packages( l_schema_names );
end;
function get_schema_names(a_paths ut_varchar2_list) return ut_varchar2_rows is
@@ -520,7 +526,7 @@ create or replace package body ut_suite_manager is
a_paths ut_varchar2_list,
a_suites out nocopy ut_suite_items,
a_random_seed positive := null,
- a_tags ut_varchar2_rows := ut_varchar2_rows()
+ a_tags varchar2 := null
) is
l_paths ut_varchar2_list := a_paths;
l_schema_names ut_varchar2_rows;
diff --git a/source/core/ut_suite_manager.pks b/source/core/ut_suite_manager.pks
index 170b83f05..60c3595bb 100644
--- a/source/core/ut_suite_manager.pks
+++ b/source/core/ut_suite_manager.pks
@@ -1,7 +1,7 @@
-create or replace package ut_suite_manager authid current_user is
+create or replace noneditionable package ut_suite_manager authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ create or replace package ut_suite_manager authid current_user is
* @param a_schema_names list of schemas to return the information for
* @return array containing unit test schema and object names
*/
- function get_schema_ut_packages(a_schema_names ut_varchar2_rows) return ut_object_names;
+ function get_schema_ut_packages(a_schema_names ut_varchar2_rows, a_schema_name_expr varchar2) return ut_object_names;
/**
* Builds a hierarchical suites based on given suite-paths
@@ -53,7 +53,7 @@ create or replace package ut_suite_manager authid current_user is
a_paths in ut_varchar2_list,
a_suites out nocopy ut_suite_items,
a_random_seed in positive := null,
- a_tags ut_varchar2_rows := ut_varchar2_rows()
+ a_tags in varchar2 := null
);
/**
diff --git a/source/core/ut_suite_tag_filter.pkb b/source/core/ut_suite_tag_filter.pkb
new file mode 100644
index 000000000..447ba47d5
--- /dev/null
+++ b/source/core/ut_suite_tag_filter.pkb
@@ -0,0 +1,290 @@
+create or replace noneditionable package body ut_suite_tag_filter is
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+ /**
+ * Constants use in postfix and infix transformations
+ */
+ gc_operators constant ut_varchar2_list := ut_varchar2_list('|','&','!');
+ gc_unary_operators constant ut_varchar2_list := ut_varchar2_list('!'); -- right side associative operator
+ gc_binary_operators constant ut_varchar2_list := ut_varchar2_list('|','&'); -- left side associative operator
+ gc_reserved_tag_words constant ut_varchar2_list := ut_varchar2_list('none','any');
+ gc_exception_msg constant varchar2(200) := 'Invalid tag expression';
+
+ type t_precedence_table is table of number index by varchar2(1);
+ g_precedence t_precedence_table;
+
+ function tokenize_tags_string(a_tags in varchar2) return ut_varchar2_list is
+ l_tags_tokens ut_varchar2_list := ut_varchar2_list();
+ begin
+ --Tokenize a string into operators and tags
+ select regexp_substr(a_tags,'([^!()|&]+)|([!()|&])', 1, level) as string_parts
+ bulk collect into l_tags_tokens
+ from dual connect by regexp_substr (a_tags, '([^!()|&]+)|([!()|&])', 1, level) is not null;
+
+ return l_tags_tokens;
+ end;
+
+ /*
+ To support a legact tag notation
+ , = OR
+ - = NOT
+ we will perform a replace of that characters into
+ new notation.
+ | = OR
+ & = AND
+ ! = NOT
+ */
+ function replace_legacy_tag_notation(a_tags varchar2
+ ) return varchar2 is
+ l_tags ut_varchar2_list := ut_utils.string_to_table(a_tags,',');
+ l_tags_include varchar2(4000);
+ l_tags_exclude varchar2(4000);
+ l_return_tag varchar2(4000);
+ begin
+ if instr(a_tags,',') > 0 or instr(a_tags,'-') > 0 then
+
+ select '('||listagg( t.column_value,'|')
+ within group( order by column_value)||')'
+ into l_tags_include
+ from table(l_tags) t
+ where t.column_value not like '-%';
+
+ select '('||listagg( replace(t.column_value,'-','!'),' & ')
+ within group( order by column_value)||')'
+ into l_tags_exclude
+ from table(l_tags) t
+ where t.column_value like '-%';
+
+
+ l_return_tag:=
+ case
+ when l_tags_include <> '()' and l_tags_exclude <> '()'
+ then l_tags_include || ' & ' || l_tags_exclude
+ when l_tags_include <> '()'
+ then l_tags_include
+ when l_tags_exclude <> '()'
+ then l_tags_exclude
+ end;
+ else
+ l_return_tag := a_tags;
+ end if;
+ return l_return_tag;
+ end;
+
+ /*
+ https://stackoverflow.com/questions/29634992/shunting-yard-validate-expression
+ */
+ function shunt_logical_expression(a_tags in ut_varchar2_list) return ut_varchar2_list is
+ l_operator_stack ut_stack := ut_stack();
+ l_rnp_tokens ut_varchar2_list := ut_varchar2_list();
+ l_token varchar2(32767);
+ l_expect_operand boolean := true;
+ l_expect_operator boolean := false;
+ l_idx pls_integer;
+ begin
+ l_idx := a_tags.first;
+ --Exuecute modified shunting algorithm
+ WHILE (l_idx is not null) loop
+ l_token := a_tags(l_idx);
+ if (l_token member of gc_operators and l_token member of gc_binary_operators) then
+ if not(l_expect_operator) then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ end if;
+ while l_operator_stack.top > 0 and (g_precedence(l_operator_stack.peek) > g_precedence(l_token)) loop
+ l_rnp_tokens.extend;
+ l_rnp_tokens(l_rnp_tokens.last) := l_operator_stack.pop;
+ end loop;
+ l_operator_stack.push(a_tags(l_idx));
+ l_expect_operand := true;
+ l_expect_operator:= false;
+ elsif (l_token member of gc_operators and l_token member of gc_unary_operators) then
+ if not(l_expect_operand) then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ end if;
+ l_operator_stack.push(a_tags(l_idx));
+ l_expect_operand := true;
+ l_expect_operator:= false;
+ elsif l_token = '(' then
+ if not(l_expect_operand) then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ end if;
+ l_operator_stack.push(a_tags(l_idx));
+ l_expect_operand := true;
+ l_expect_operator:= false;
+ elsif l_token = ')' then
+ if not(l_expect_operator) then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ end if;
+ while l_operator_stack.peek <> '(' loop
+ l_rnp_tokens.extend;
+ l_rnp_tokens(l_rnp_tokens.last) := l_operator_stack.pop;
+ end loop;
+ l_operator_stack.pop; --Pop the open bracket and discard it
+ l_expect_operand := false;
+ l_expect_operator:= true;
+ else
+ if not(l_expect_operand) then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ end if;
+ l_rnp_tokens.extend;
+ l_rnp_tokens(l_rnp_tokens.last) :=l_token;
+ l_expect_operator := true;
+ l_expect_operand := false;
+ end if;
+
+ l_idx := a_tags.next(l_idx);
+ end loop;
+
+ while l_operator_stack.peek is not null loop
+ if l_operator_stack.peek in ('(',')') then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ end if;
+ l_rnp_tokens.extend;
+ l_rnp_tokens(l_rnp_tokens.last):=l_operator_stack.pop;
+ end loop;
+
+ return l_rnp_tokens;
+ end shunt_logical_expression;
+
+ function conv_postfix_to_infix_sql(a_postfix_exp in ut_varchar2_list,a_tags_column_name in varchar2)
+ return varchar2 is
+ l_infix_stack ut_stack := ut_stack();
+ l_right_side varchar2(32767);
+ l_left_side varchar2(32767);
+ l_infix_exp varchar2(32767);
+ l_member_token varchar2(20) := ' member of '||a_tags_column_name;
+ l_idx pls_integer;
+ begin
+ l_idx := a_postfix_exp.first;
+ while ( l_idx is not null) loop
+ --If the token we got is a none or any keyword
+ if a_postfix_exp(l_idx) member of gc_reserved_tag_words then
+
+ l_infix_stack.push(
+ case
+ when a_postfix_exp(l_idx) = 'none' then '('||a_tags_column_name||' is empty or '||a_tags_column_name||' is null)'
+ else a_tags_column_name||' is not empty'
+ end
+ );
+ --If token is operand but also single tag
+ elsif regexp_count(a_postfix_exp(l_idx),'[!()|&]') = 0 then
+ l_infix_stack.push(q'[']'||a_postfix_exp(l_idx)||q'[']'||l_member_token);
+ --If token is unary operator not
+ elsif a_postfix_exp(l_idx) member of gc_unary_operators then
+ l_right_side := l_infix_stack.pop;
+ l_infix_exp := a_postfix_exp(l_idx)||'('||l_right_side||')';
+ l_infix_stack.push(l_infix_exp);
+ --If token is binary operator
+ elsif a_postfix_exp(l_idx) member of gc_binary_operators then
+ l_right_side := l_infix_stack.pop;
+ l_left_side := l_infix_stack.pop;
+ l_infix_exp := '('||l_left_side||a_postfix_exp(l_idx)||l_right_side||')';
+ l_infix_stack.push(l_infix_exp);
+ end if;
+ l_idx := a_postfix_exp.next(l_idx);
+ end loop;
+
+ return l_infix_stack.pop;
+ end conv_postfix_to_infix_sql;
+
+ function create_where_filter(a_tags varchar2
+ ) return varchar2 is
+ l_tags varchar2(4000);
+ begin
+ l_tags := replace(replace_legacy_tag_notation(a_tags),' ');
+ l_tags := conv_postfix_to_infix_sql(shunt_logical_expression(tokenize_tags_string(l_tags)),'tags');
+ l_tags := replace(l_tags, '|',' or ');
+ l_tags := replace(l_tags ,'&',' and ');
+ l_tags := replace(l_tags ,'!','not');
+ return l_tags;
+ end;
+
+
+ /*
+ Having a base set of suites we will do a further filter down if there are
+ any tags defined.
+ */
+ function get_tags_suites (
+ a_suite_items ut_suite_cache_rows,
+ a_tags varchar2
+ ) return ut_suite_cache_rows is
+ l_results ut_suite_cache_rows;
+ l_sql varchar2(32000);
+ l_tags_filter_clause varchar2(4000):= create_where_filter(a_tags);
+ begin
+ l_sql :=
+ q'[
+ with
+ suites_mv as (
+ select c.id,value(c) as obj,c.path as path,c.self_type,c.object_owner,c.tags as tags
+ from table(:suite_items) c
+ ),
+ propagate_tags_from_ancestors as (
+ select c.id, c.self_type, c.path, c.object_owner, cast(collect(c_tags.tag) as ut_varchar2_rows) as tags
+ from suites_mv c
+ left join suites_mv t
+ on t.self_type in ('UT_SUITE','UT_SUITE_CONTEXT')
+ and c.path like t.path||'.%' /* all descendants */
+ and c.object_owner = t.object_owner
+ outer apply (select column_value tag from table(c.tags) union select column_value tag from table(t.tags) ) c_tags
+ group by c.id, c.self_type, c.path, c.object_owner
+ ),
+ filter_by_tags as (
+ select *
+ from propagate_tags_from_ancestors x
+ where ( ]'||l_tags_filter_clause||q'[ )
+ ),
+ only_items_with_tests as (
+ select item.obj
+ from suites_mv item
+ where exists (
+ select 1
+ from filter_by_tags tst
+ where tst.self_type in ('UT_TEST')
+ and (tst.path||'.' like item.path || '.%' /*all descendants and self*/ and item.object_owner = tst.object_owner)
+ )
+ )
+ select obj from only_items_with_tests]';
+ execute immediate l_sql bulk collect into l_results using a_suite_items;
+
+ return l_results;
+ end;
+
+ function apply(
+ a_unfiltered_rows ut_suite_cache_rows,
+ a_tags varchar2 := null
+ ) return ut_suite_cache_rows is
+ l_suite_items ut_suite_cache_rows := a_unfiltered_rows;
+ begin
+ if length(a_tags) > 0 then
+ l_suite_items := get_tags_suites(l_suite_items,a_tags);
+ end if;
+
+ return l_suite_items;
+ end;
+
+begin
+ --Define operators precedence
+ g_precedence('!'):=4;
+ g_precedence('&'):=3;
+ g_precedence('|'):=2;
+ g_precedence(')'):=1;
+ g_precedence('('):=1;
+
+end ut_suite_tag_filter;
+/
diff --git a/source/core/ut_suite_tag_filter.pks b/source/core/ut_suite_tag_filter.pks
new file mode 100644
index 000000000..bb3d4ad73
--- /dev/null
+++ b/source/core/ut_suite_tag_filter.pks
@@ -0,0 +1,55 @@
+create or replace noneditionable package ut_suite_tag_filter authid definer is
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+ /**
+ * Package that will filter suites by tags
+ *
+ */
+
+ /*
+ * Return table of tokens character by character
+ */
+ function tokenize_tags_string(a_tags in varchar2) return ut_varchar2_list;
+
+ /*
+ * Function that uses Dijkstra algorithm to parse mathematical and logical expression
+ * and return a list of elements in Reverse Polish Notation ( postfix )
+ * As part of execution it will validate expression.
+ */
+ function shunt_logical_expression(a_tags in ut_varchar2_list) return ut_varchar2_list;
+
+ /*
+ * Function that converts postfix notation into infix and creating a string of sql filter
+ * that checking a tags collections for tags according to posted logic.
+ */
+ function conv_postfix_to_infix_sql(a_postfix_exp in ut_varchar2_list,a_tags_column_name in varchar2)
+ return varchar2;
+
+ /*
+ * Generates a part where clause sql
+ */
+ function create_where_filter(a_tags varchar2)
+ return varchar2;
+
+ function apply(
+ a_unfiltered_rows ut_suite_cache_rows,
+ a_tags varchar2 := null
+ ) return ut_suite_cache_rows;
+
+end ut_suite_tag_filter;
+/
diff --git a/source/core/ut_utils.pkb b/source/core/ut_utils.pkb
index 162e50f8f..c8ced3bb9 100644
--- a/source/core/ut_utils.pkb
+++ b/source/core/ut_utils.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_utils is
+create or replace noneditionable package body ut_utils is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -19,10 +19,13 @@ create or replace package body ut_utils is
/**
* Constants regex used to validate XML name
*/
- gc_invalid_first_xml_char constant varchar2(50) := '[^_a-zA-Z]';
- gc_invalid_xml_char constant varchar2(50) := '[^_a-zA-Z0-9\.-]';
- gc_full_valid_xml_name constant varchar2(50) := '^([_a-zA-Z])([_a-zA-Z0-9\.-])*$';
+ gc_invalid_first_xml_char constant varchar2(50) := '[^_[:alpha:]]';
+ gc_invalid_xml_char constant varchar2(50) := '[^_[:alnum:]\.-]';
+ gc_full_valid_xml_name constant varchar2(50) := '^([[:alpha:]])([_[:alnum:]\.-])*$';
gc_owner_hash constant integer(11) := dbms_utility.get_hash_value( ut_owner(), 0, power(2,31)-1);
+ gc_open_chars constant varchar2(4):= '[{(<';
+ gc_close_chars constant varchar2(4):= ']})>';
+ gc_max_plsql_source_len constant integer := 32767;
function surround_with(a_value varchar2, a_quote_char varchar2) return varchar2 is
begin
@@ -91,8 +94,8 @@ create or replace package body ut_utils is
a_max_output_len in number := gc_max_output_string_length
) return varchar2 is
l_result varchar2(32767);
- c_length constant integer := coalesce( length( a_value ), 0 );
- c_max_input_string_length constant integer := a_max_output_len - coalesce( length( a_quote_char ) * 2, 0 );
+ c_length constant integer := coalesce( lengthb( a_value ), 0 );
+ c_max_input_string_length constant integer := a_max_output_len - coalesce( lengthb( a_quote_char ) * 2, 0 );
c_overflow_substr_len constant integer := c_max_input_string_length - gc_more_data_string_len;
begin
if c_length = 0 then
@@ -111,8 +114,8 @@ create or replace package body ut_utils is
a_max_output_len in number := gc_max_output_string_length
) return varchar2 is
l_result varchar2(32767);
- c_length constant integer := coalesce(dbms_lob.getlength(a_value), 0);
- c_max_input_string_length constant integer := a_max_output_len - coalesce( length( a_quote_char ) * 2, 0 );
+ c_length constant integer := coalesce(ut_utils.lengthb_clob(a_value), 0);
+ c_max_input_string_length constant integer := a_max_output_len - coalesce( lengthb( a_quote_char ) * 2, 0 );
c_overflow_substr_len constant integer := c_max_input_string_length - gc_more_data_string_len;
begin
if a_value is null then
@@ -134,7 +137,7 @@ create or replace package body ut_utils is
) return varchar2 is
l_result varchar2(32767);
c_length constant integer := coalesce(dbms_lob.getlength(a_value), 0);
- c_max_input_string_length constant integer := a_max_output_len - coalesce( length( a_quote_char ) * 2, 0 );
+ c_max_input_string_length constant integer := a_max_output_len - coalesce( lengthb( a_quote_char ) * 2, 0 );
c_overflow_substr_len constant integer := c_max_input_string_length - gc_more_data_string_len;
begin
if a_value is null then
@@ -411,7 +414,7 @@ create or replace package body ut_utils is
if a_list is null then
a_list := ut_varchar2_rows();
end if;
- if length(a_item) > gc_max_storage_varchar2_len then
+ if lengthb(a_item) > gc_max_storage_varchar2_len then
append_to_list(
a_list,
ut_utils.convert_collection(
@@ -467,7 +470,7 @@ create or replace package body ut_utils is
l_result := ut_varchar2_rows();
for i in 1 .. a_collection.count loop
l_result.extend();
- l_result(i) := substr(a_collection(i),1,gc_max_storage_varchar2_len);
+ l_result(i) := substrb(a_collection(i),1,gc_max_storage_varchar2_len);
end loop;
end if;
return l_result;
@@ -570,6 +573,7 @@ create or replace package body ut_utils is
end loop;
exit when l_lines_data%notfound;
end loop;
+ close l_lines_data;
execute immediate 'truncate table ut_dbms_output_cache';
commit;
end;
@@ -656,94 +660,234 @@ create or replace package body ut_utils is
return l_result;
end;
- function replace_multiline_comments(a_source clob) return clob is
- l_result clob;
- l_ml_comment_start binary_integer := 1;
- l_comment_start binary_integer := 1;
- l_text_start binary_integer := 1;
- l_escaped_text_start binary_integer := 1;
- l_escaped_text_end_char varchar2(1 char);
- l_end binary_integer := 1;
- l_ml_comment clob;
- l_newlines_count binary_integer;
- l_offset binary_integer := 1;
- l_length binary_integer := coalesce(dbms_lob.getlength(a_source), 0);
- begin
- l_ml_comment_start := instr(a_source,'/*');
- l_comment_start := instr(a_source,'--');
- l_text_start := instr(a_source,'''');
- l_escaped_text_start := instr(a_source,q'[q']');
- while l_offset > 0 and l_ml_comment_start > 0 loop
-
- if l_ml_comment_start > 0 and (l_ml_comment_start < l_comment_start or l_comment_start = 0)
- and (l_ml_comment_start < l_text_start or l_text_start = 0)and (l_ml_comment_start < l_escaped_text_start or l_escaped_text_start = 0)
- then
- l_end := instr(a_source,'*/',l_ml_comment_start+2);
- append_to_clob(l_result, dbms_lob.substr(a_source, l_ml_comment_start-l_offset, l_offset));
+ function scan_line(a_line in varchar2, a_in_ml_comment in out boolean) return varchar2 is
+ -- Normal scan
+ l_remaining varchar2(32767) := a_line;
+ l_line varchar2(32767);
+ l_ml_start binary_integer;
+ l_comment_start binary_integer;
+ l_text_start binary_integer;
+ l_eq_text_start binary_integer;
+ l_eq_end_char varchar2(1 char);
+ l_pos binary_integer;
+ l_end binary_integer;
+ l_ml_end binary_integer;
+ begin
+ if a_in_ml_comment then
+ l_ml_end := instr(l_remaining, '*/');
+ if l_ml_end > 0 then
+ a_in_ml_comment := false;
+ l_remaining := substr(l_remaining, l_ml_end + 2);
+ else
+ return null;
+ end if;
+ end if;
+
+ loop
+ exit when l_remaining is null;
+ l_ml_start := instr(l_remaining, '/*');
+ l_comment_start := instr(l_remaining, '--');
+ l_text_start := instr(l_remaining, '''');
+ -- q' always puts ' at l_text_start; just check the char immediately before it
+ l_eq_text_start := case
+ when l_text_start > 1 and substr(l_remaining, l_text_start - 1, 1) = 'q'
+ then l_text_start - 1
+ else 0
+ end;
+ -- Sentinel gc_max_plsql_source_len means "not present"; 32767 is beyond any VARCHAR2 position
+ l_pos := least(
+ case when l_ml_start > 0 then l_ml_start else gc_max_plsql_source_len end,
+ case when l_comment_start > 0 then l_comment_start else gc_max_plsql_source_len end,
+ case when l_text_start > 0 then l_text_start else gc_max_plsql_source_len end,
+ case when l_eq_text_start > 0 then l_eq_text_start else gc_max_plsql_source_len end
+ );
+
+ if l_pos = gc_max_plsql_source_len then
+ l_line := l_line || l_remaining;
+ exit;
+ end if;
+
+ l_line := l_line || substr(l_remaining, 1, l_pos - 1);
+ l_remaining := substr(l_remaining, l_pos);
+ -- l_remaining now starts exactly at the token; all branch offsets below are relative to 1
+ if l_pos = l_eq_text_start then
+ -- q-quoted string: l_remaining starts at 'q', delimiter is at position 3
+ l_eq_end_char := translate(substr(l_remaining, 3, 1), gc_open_chars, gc_close_chars);
+ l_end := instr(l_remaining, l_eq_end_char || '''', 4);
if l_end > 0 then
- l_ml_comment := substr(a_source, l_ml_comment_start, l_end-l_ml_comment_start);
- l_newlines_count := length( l_ml_comment ) - length( translate( l_ml_comment, 'a'||chr(10), 'a') );
- if l_newlines_count > 0 then
- append_to_clob(l_result, lpad( chr(10), l_newlines_count, chr(10) ) );
- end if;
- l_end := l_end + 2;
+ l_line := l_line || substr(l_remaining, 1, l_end + 1);
+ l_remaining := substr(l_remaining, l_end + 2);
+ else
+ l_line := l_line || l_remaining;
+ exit;
end if;
- else
- if l_comment_start > 0 and (l_comment_start < l_ml_comment_start or l_ml_comment_start = 0)
- and (l_comment_start < l_text_start or l_text_start = 0) and (l_comment_start < l_escaped_text_start or l_escaped_text_start = 0)
- then
- l_end := instr(a_source,chr(10),l_comment_start+2);
- if l_end > 0 then
- l_end := l_end + 1;
- end if;
- elsif l_text_start > 0 and (l_text_start < l_ml_comment_start or l_ml_comment_start = 0)
- and (l_text_start < l_comment_start or l_comment_start = 0) and (l_text_start < l_escaped_text_start or l_escaped_text_start = 0)
- then
- l_end := instr(a_source,q'[']',l_text_start+1);
-
- --skip double quotes while searching for end of quoted text
- while l_end > 0 and l_end = instr(a_source,q'['']',l_text_start+1) loop
- l_end := instr(a_source,q'[']',l_end+1);
- end loop;
- if l_end > 0 then
- l_end := l_end + 1;
+ elsif l_pos = l_ml_start then
+ -- Multi-line comment: l_remaining starts at '/*', so end search starts at 3
+ l_ml_end := instr(l_remaining, '*/', 3);
+ if l_ml_end > 0 then
+ l_remaining := substr(l_remaining, l_ml_end + 2);
+ else
+ a_in_ml_comment := true;
+ -- preserve trailing newline if present — it belongs to this line, not the comment
+ if substr(l_remaining, -1) = chr(10) then
+ l_line := l_line || chr(10);
end if;
+ return l_line;
+ end if;
- elsif l_escaped_text_start > 0 and (l_escaped_text_start < l_ml_comment_start or l_ml_comment_start = 0)
- and (l_escaped_text_start < l_comment_start or l_comment_start = 0) and (l_escaped_text_start < l_text_start or l_text_start = 0)
- then
- --translate char "[" from the start of quoted text "q'[someting]'" into "]"
- l_escaped_text_end_char := translate( substr(a_source, l_escaped_text_start + 2, 1), '[{(<', ']})>');
- l_end := instr(a_source,l_escaped_text_end_char||'''',l_escaped_text_start + 3 );
- if l_end > 0 then
- l_end := l_end + 2;
+ elsif l_pos = l_comment_start then
+ -- Single-line comment: everything from here is comment, keep and stop
+ l_line := l_line || l_remaining;
+ return l_line;
+
+ else
+ -- Regular string literal: l_remaining starts at the opening quote
+ -- scan from position 2 to skip the opening quote
+ l_end := 2;
+ loop
+ l_end := instr(l_remaining, '''', l_end);
+ exit when l_end = 0;
+ if substr(l_remaining, l_end, 2) = '''''' then
+ l_end := l_end + 2; -- skip escaped quote pair
+ else
+ exit; -- real closing quote
end if;
- end if;
+ end loop;
- if l_end = 0 then
- append_to_clob(l_result, substr(a_source, l_offset, l_length-l_offset));
+ if l_end > 0 then
+ l_line := l_line || substr(l_remaining, 1, l_end);
+ l_remaining := substr(l_remaining, l_end + 1);
else
- append_to_clob(l_result, substr(a_source, l_offset, l_end-l_offset));
+ l_line := l_line || l_remaining;
+ exit;
end if;
+
end if;
- l_offset := l_end;
- if l_offset >= l_ml_comment_start then
- l_ml_comment_start := instr(a_source,'/*',l_offset);
+ end loop;
+
+ return l_line;
+ end;
+
+ function replace_multiline_comments(a_source dbms_preprocessor.source_lines_t)
+ return dbms_preprocessor.source_lines_t
+ is
+ l_result dbms_preprocessor.source_lines_t;
+ l_line varchar2(32767);
+ l_remaining varchar2(32767);
+ l_in_ml_comment boolean := false;
+ l_ml_end binary_integer;
+ l_has_ml_comment boolean := false;
+ begin
+ if a_source.count = 0 then
+ return a_source;
+ end if;
+
+ -- Fast pre-scan to check for presence of multi-line comments; if none, return original source unmodified
+ for i in 1 .. a_source.count loop
+ if instr(a_source(i), '/*') > 0 then
+ l_has_ml_comment := true;
+ exit;
end if;
- if l_offset >= l_comment_start then
- l_comment_start := instr(a_source,'--',l_offset);
+ end loop;
+
+ if not l_has_ml_comment then
+ return a_source;
+ end if;
+
+ for i in 1 .. a_source.count loop
+ l_line := a_source(i);
+
+ -- Fast path: inside multi-line comment
+ if l_in_ml_comment then
+ l_ml_end := instr(l_line, '*/');
+ if l_ml_end > 0 then
+ l_in_ml_comment := false;
+ l_line := substr(l_line, l_ml_end + 2);
+ -- fall through to normal scan
+ else
+ l_result(i) := '';
+ continue;
+ end if;
end if;
- if l_offset >= l_text_start then
- l_text_start := instr(a_source,'''',l_offset);
+
+ -- Fast path: no special tokens on this line
+ if instr(l_line, '/') = 0
+ and instr(l_line, '-') = 0
+ and instr(l_line, '''') = 0
+ then
+ l_result(i) := l_line;
+ continue;
end if;
- if l_offset >= l_escaped_text_start then
- l_escaped_text_start := instr(a_source,q'[q']',l_offset);
+
+ -- Normal scan
+ l_remaining := l_line;
+ l_line := scan_line(l_remaining, l_in_ml_comment);
+ if l_line is null then
+ l_line := '';
end if;
+ l_result(i) := l_line;
end loop;
- append_to_clob(l_result, substr(a_source, l_end));
+
return l_result;
- end;
+ end replace_multiline_comments;
+
+ function strip_create_header_lines(a_source dbms_preprocessor.source_lines_t)
+ return dbms_preprocessor.source_lines_t
+ is
+ l_result dbms_preprocessor.source_lines_t := a_source;
+ l_rebased dbms_preprocessor.source_lines_t;
+ l_create_line pls_integer;
+ l_header_line pls_integer;
+ l_header_pos pls_integer := 0;
+ begin
+ if l_result.count = 0 then
+ return l_result;
+ end if;
+
+ -- remove comment lines that contain "-- create or replace" and find first CREATE
+ for i in 1..l_result.count loop
+ l_result(i) := regexp_replace(l_result(i), '^.*[-]{2,}\s*create(\s+or\s+replace).*$', null, 1, 1, 'i');
+ if l_create_line is null and regexp_like(l_result(i), '(^|[[:space:]])create([[:space:]]|$)', 'i') then
+ l_create_line := i;
+ end if;
+ end loop;
+
+ -- find first occurrence of object keyword after CREATE (may be on later line)
+ if l_create_line is not null then
+ for i in l_create_line..l_result.count loop
+ l_header_pos := regexp_instr(
+ l_result(i),
+ '(^|[[:space:]])(package|type|procedure|function)([[:space:]]|$)',
+ 1, 1, 0, 'i', 2
+ );
+ if l_header_pos > 0 then
+ l_header_line := i;
+ exit;
+ end if;
+ end loop;
+
+ if l_header_line is not null then
+ -- keep from keyword onward on the header line
+ l_result(l_header_line) := substr(l_result(l_header_line), l_header_pos);
+ -- remove "OWNER." from create or replace statement.
+ -- Owner is not supported along with AUTHID - see issue https://github.com/utPLSQL/utPLSQL/issues/1088
+ l_result(l_header_line) := regexp_replace(
+ l_result(l_header_line),
+ '^(package|type|procedure|function)\s+("?[[:alpha:]][[:alnum:]$#_]*"?\.)(.*)',
+ '\1 \3', 1, 1, 'ni'
+ );
+
+ -- rebase so header line becomes line 1 (matches preprocessor expectations)
+ for i in l_header_line .. l_result.count loop
+ l_rebased(i - l_header_line + 1) := l_result(i);
+ end loop;
+ return l_rebased;
+ end if;
+ end if;
+
+ return l_result;
+ end strip_create_header_lines;
function get_child_reporters(a_for_reporters ut_reporters_info := null) return ut_reporters_info is
l_for_reporters ut_reporters_info := a_for_reporters;
@@ -880,13 +1024,13 @@ create or replace package body ut_utils is
return regexp_replace(a_item,a_prefix||a_connector);
end;
- function get_hash(a_data raw, a_hash_type binary_integer := dbms_crypto.hash_sh1) return t_hash is
+ function get_hash(a_data raw, a_hash_type binary_integer := dbms_crypto.hash_sh256) return t_hash is
begin
--We cannot run hash on null
return case when a_data is null then null else dbms_crypto.hash(a_data, a_hash_type) end;
end;
- function get_hash(a_data clob, a_hash_type binary_integer := dbms_crypto.hash_sh1) return t_hash is
+ function get_hash(a_data clob, a_hash_type binary_integer := dbms_crypto.hash_sh256) return t_hash is
begin
--We cannot run hash on null
return case when a_data is null then null else dbms_crypto.hash(a_data, a_hash_type) end;
@@ -990,5 +1134,37 @@ create or replace package body ut_utils is
end;
+ /*
+ * Inspired by
+ * https://stackoverflow.com/a/48782891
+ */
+ function lengthb_clob( a_clob clob) return integer is
+ l_blob blob;
+ l_desc_offset PLS_INTEGER := 1;
+ l_src_offset PLS_INTEGER := 1;
+ l_lang PLS_INTEGER := 0;
+ l_warning PLS_INTEGER := 0;
+ l_result integer;
+ begin
+ if a_clob = empty_clob() then
+ l_result := 0;
+ elsif a_clob is not null then
+ dbms_lob.createtemporary(l_blob,true);
+ dbms_lob.converttoblob
+ ( l_blob
+ , a_clob
+ , dbms_lob.getlength(a_clob)
+ , l_desc_offset
+ , l_src_offset
+ , dbms_lob.default_csid
+ , l_lang
+ , l_warning
+ );
+ l_result := length(l_blob);
+ dbms_lob.freetemporary(l_blob);
+ end if;
+ return l_result;
+ end;
+
end ut_utils;
/
diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks
index 6ef2c4a9a..46c28f0f0 100644
--- a/source/core/ut_utils.pks
+++ b/source/core/ut_utils.pks
@@ -1,7 +1,7 @@
-create or replace package ut_utils authid definer is
+create or replace noneditionable package ut_utils authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is
*
*/
- gc_version constant varchar2(50) := 'v3.1.13.4015-develop';
+ gc_version constant varchar2(50) := 'v3.2.4.4532-develop';
subtype t_executable_type is varchar2(30);
gc_before_all constant t_executable_type := 'beforeall';
@@ -121,6 +121,10 @@ create or replace package ut_utils authid definer is
ex_failed_open_cur exception;
gc_failed_open_cur constant pls_integer := -20218;
pragma exception_init (ex_failed_open_cur, -20218);
+
+ ex_invalid_tag_expression exception;
+ gc_invalid_tag_expression constant pls_integer := -20219;
+ pragma exception_init (ex_invalid_tag_expression, -20219);
gc_max_storage_varchar2_len constant integer := 4000;
gc_max_output_string_length constant integer := 4000;
@@ -401,7 +405,15 @@ create or replace package ut_utils authid definer is
/**
* Replaces multi-line comments in given source-code with empty lines
*/
- function replace_multiline_comments(a_source clob) return clob;
+ function replace_multiline_comments(a_source dbms_preprocessor.source_lines_t)
+ return dbms_preprocessor.source_lines_t;
+
+ /**
+ * Strips the CREATE header (possibly split across lines) so source starts at
+ * package/type/procedure/function keyword, preserving line numbers.
+ */
+ function strip_create_header_lines(a_source dbms_preprocessor.source_lines_t)
+ return dbms_preprocessor.source_lines_t;
/**
* Returns list of sub-type reporters for given list of super-type reporters
@@ -445,12 +457,12 @@ create or replace package ut_utils authid definer is
/*
* Wrapper function for calling dbms_crypto.hash
*/
- function get_hash(a_data raw, a_hash_type binary_integer := dbms_crypto.hash_sh1) return t_hash;
+ function get_hash(a_data raw, a_hash_type binary_integer := dbms_crypto.hash_sh256) return t_hash;
/*
* Wrapper function for calling dbms_crypto.hash
*/
- function get_hash(a_data clob, a_hash_type binary_integer := dbms_crypto.hash_sh1) return t_hash;
+ function get_hash(a_data clob, a_hash_type binary_integer := dbms_crypto.hash_sh256) return t_hash;
/*
* Returns a hash value of suitepath based on input path and random seed
@@ -472,6 +484,11 @@ create or replace package ut_utils authid definer is
* Return value of interval in plain english
*/
function interval_to_text(a_interval yminterval_unconstrained) return varchar2;
+
+ /*
+ * Return length of CLOB in bytes. Null for NULL
+ */
+ function lengthb_clob( a_clob clob) return integer;
end ut_utils;
/
diff --git a/source/create_grants.sql b/source/create_grants.sql
index 8a44ab371..9318a7220 100644
--- a/source/create_grants.sql
+++ b/source/create_grants.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -104,10 +104,10 @@ grant execute on &&ut3_owner..ut_tfs_junit_reporter to &ut3_user;
grant execute on &&ut3_owner..ut_documentation_reporter to &ut3_user;
grant execute on &&ut3_owner..ut_sonar_test_reporter to &ut3_user;
grant execute on &&ut3_owner..ut_realtime_reporter to &ut3_user;
+grant execute on &&ut3_owner..ut_tap_reporter to &ut3_user;
--reporters - coverage
grant execute on &&ut3_owner..ut_coverage_html_reporter to &ut3_user;
grant execute on &&ut3_owner..ut_coverage_sonar_reporter to &ut3_user;
-grant execute on &&ut3_owner..ut_coveralls_reporter to &ut3_user;
grant execute on &&ut3_owner..ut_coverage_cobertura_reporter to &ut3_user;
--reporters - debug
grant execute on &&ut3_owner..ut_debug_reporter to &ut3_user;
@@ -123,6 +123,7 @@ grant execute on &&ut3_owner..ut_console_reporter_base to &ut3_user;
grant execute on &&ut3_owner..ut_output_buffer_base to &ut3_user;
grant execute on &&ut3_owner..ut_output_table_buffer to &ut3_user;
grant execute on &&ut3_owner..ut_output_clob_table_buffer to &ut3_user;
+grant execute on &&ut3_owner..ut_output_bulk_buffer to &ut3_user;
--needed internally for selecting from annotation objects within packages that use invoker rights
grant execute on &&ut3_owner..ut_annotation_objs_cache_info to &ut3_user;
diff --git a/source/create_synonyms.sql b/source/create_synonyms.sql
index fa1c1dc45..ab338f4f7 100644
--- a/source/create_synonyms.sql
+++ b/source/create_synonyms.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -36,10 +36,10 @@ set termout off
spool params.sql.tmp
select
case
- when upper('&&ut3_user') = 'PUBLIC' then q'[define action_type='or replace public'
+ when upper('&&ut3_user') = 'PUBLIC' then q'[define action_type='or replace noneditionable public'
]'||q'[define ut3_user=''
]'||q'[define grantee='PUBLIC']'
- else q'[define action_type='or replace'
+ else q'[define action_type='or replace noneditionable'
]'||q'[define grantee='&&ut3_user']
]'||q'[define ut3_user='&&ut3_user..']'
end
@@ -119,10 +119,10 @@ create &action_type. synonym &ut3_user.ut_tfs_junit_reporter for &&ut3_owner..ut
create &action_type. synonym &ut3_user.ut_documentation_reporter for &&ut3_owner..ut_documentation_reporter;
create &action_type. synonym &ut3_user.ut_sonar_test_reporter for &&ut3_owner..ut_sonar_test_reporter;
create &action_type. synonym &ut3_user.ut_realtime_reporter for &&ut3_owner..ut_realtime_reporter;
+create &action_type. synonym &ut3_user.ut_tap_reporter for &&ut3_owner..ut_tap_reporter;
--reporters - coverage
create &action_type. synonym &ut3_user.ut_coverage_html_reporter for &&ut3_owner..ut_coverage_html_reporter;
create &action_type. synonym &ut3_user.ut_coverage_sonar_reporter for &&ut3_owner..ut_coverage_sonar_reporter;
-create &action_type. synonym &ut3_user.ut_coveralls_reporter for &&ut3_owner..ut_coveralls_reporter;
create &action_type. synonym &ut3_user.ut_coverage_cobertura_reporter for &&ut3_owner..ut_coverage_cobertura_reporter;
--reporters - debug
create &action_type. synonym &ut3_user.ut_debug_reporter for &&ut3_owner..ut_debug_reporter;
diff --git a/source/create_synonyms_and_grants_for_public.sql b/source/create_synonyms_and_grants_for_public.sql
index 050162d72..25f14217e 100644
--- a/source/create_synonyms_and_grants_for_public.sql
+++ b/source/create_synonyms_and_grants_for_public.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/create_user_grants.sql b/source/create_user_grants.sql
index 83e594884..c1b81efa4 100644
--- a/source/create_user_grants.sql
+++ b/source/create_user_grants.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/create_user_synonyms.sql b/source/create_user_synonyms.sql
index a1e7a6acc..7b0e49553 100644
--- a/source/create_user_synonyms.sql
+++ b/source/create_user_synonyms.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/create_utplsql_owner.sql b/source/create_utplsql_owner.sql
index 1af2cf168..a5b70ffda 100644
--- a/source/create_utplsql_owner.sql
+++ b/source/create_utplsql_owner.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -31,16 +31,13 @@ create user &ut3_owner_schema identified by "&ut3_password" default tablespace &
grant create session, create sequence, create procedure, create type, create table, create view, create synonym to &ut3_owner_schema;
-begin
- $if dbms_db_version.version < 18 $then
- execute immediate 'grant execute on dbms_lock to &ut3_owner_schema';
- $else
- null;
- $end
-end;
-/
-
+grant execute on dbms_lock to &ut3_owner_schema;
grant execute on dbms_crypto to &ut3_owner_schema;
+grant execute on dbms_lob to &ut3_owner_schema;
+grant execute on dbms_xmlgen to &ut3_owner_schema;
+grant execute on dbms_sql to &ut3_owner_schema;
+grant execute on dbms_random to &ut3_owner_schema;
+
grant alter session to &ut3_owner_schema;
diff --git a/source/define_ut3_owner_param.sql b/source/define_ut3_owner_param.sql
index 259b49712..192e810b7 100644
--- a/source/define_ut3_owner_param.sql
+++ b/source/define_ut3_owner_param.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_compound_data_diff_tmp.sql b/source/expectations/data_values/ut_compound_data_diff_tmp.sql
index c10e8d2e8..edd27f766 100644
--- a/source/expectations/data_values/ut_compound_data_diff_tmp.sql
+++ b/source/expectations/data_values/ut_compound_data_diff_tmp.sql
@@ -1,7 +1,7 @@
create global temporary table ut_compound_data_diff_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/expectations/data_values/ut_compound_data_helper.pkb b/source/expectations/data_values/ut_compound_data_helper.pkb
index 4517cd43c..763c133d7 100644
--- a/source/expectations/data_values/ut_compound_data_helper.pkb
+++ b/source/expectations/data_values/ut_compound_data_helper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_compound_data_helper is
+create or replace noneditionable package body ut_compound_data_helper is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -300,8 +300,8 @@ create or replace package body ut_compound_data_helper is
ut_utils.append_to_clob(a_partition_stmt,' row_number() over (partition by '||l_partition_tmp||' order by '||l_partition_tmp||' ) ');
if a_pk_table.count > 0 then
- -- If key defined do the join or these and where on diffrences
- a_join_by_stmt := ut_utils.table_to_clob(l_join_by_list, ' and ');
+ -- If key defined do the join or these and where on diffrences as well as on duplicate number when rows are same.
+ a_join_by_stmt := ' e."UT3$_Dup#No" = a."UT3$_Dup#No" and '||ut_utils.table_to_clob(l_join_by_list, ' and ');
elsif a_unordered then
-- If no key defined do the join on all columns
a_join_by_stmt := ' e."UT3$_Dup#No" = a."UT3$_Dup#No" and '||ut_utils.table_to_clob(l_equal_list, ' and ');
diff --git a/source/expectations/data_values/ut_compound_data_helper.pks b/source/expectations/data_values/ut_compound_data_helper.pks
index 451cd9bac..6069920c9 100644
--- a/source/expectations/data_values/ut_compound_data_helper.pks
+++ b/source/expectations/data_values/ut_compound_data_helper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_compound_data_helper authid definer is
+create or replace noneditionable package ut_compound_data_helper authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_compound_data_tmp.sql b/source/expectations/data_values/ut_compound_data_tmp.sql
index 1bfa77fca..01cedd97b 100644
--- a/source/expectations/data_values/ut_compound_data_tmp.sql
+++ b/source/expectations/data_values/ut_compound_data_tmp.sql
@@ -1,7 +1,7 @@
create global temporary table ut_compound_data_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/expectations/data_values/ut_compound_data_value.tpb b/source/expectations/data_values/ut_compound_data_value.tpb
index 2c52ff8fa..7db47827e 100644
--- a/source/expectations/data_values/ut_compound_data_value.tpb
+++ b/source/expectations/data_values/ut_compound_data_value.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_compound_data_value as
+create or replace noneditionable type body ut_compound_data_value as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_compound_data_value.tps b/source/expectations/data_values/ut_compound_data_value.tps
index c14dadceb..c84a59db6 100644
--- a/source/expectations/data_values/ut_compound_data_value.tps
+++ b/source/expectations/data_values/ut_compound_data_value.tps
@@ -1,7 +1,7 @@
-create or replace type ut_compound_data_value force under ut_data_value(
+create or replace noneditionable type ut_compound_data_value force under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_cursor_column.tpb b/source/expectations/data_values/ut_cursor_column.tpb
index a9fb6b0f4..3513de23e 100644
--- a/source/expectations/data_values/ut_cursor_column.tpb
+++ b/source/expectations/data_values/ut_cursor_column.tpb
@@ -1,5 +1,21 @@
-create or replace type body ut_cursor_column as
-
+create or replace noneditionable type body ut_cursor_column as
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
member procedure init(
self in out nocopy ut_cursor_column,
a_col_name varchar2, a_col_schema_name varchar2,
diff --git a/source/expectations/data_values/ut_cursor_column.tps b/source/expectations/data_values/ut_cursor_column.tps
index 77bf78f01..fcf3fe002 100644
--- a/source/expectations/data_values/ut_cursor_column.tps
+++ b/source/expectations/data_values/ut_cursor_column.tps
@@ -1,7 +1,7 @@
-create or replace type ut_cursor_column authid current_user as object (
+create or replace noneditionable type ut_cursor_column authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_cursor_column_tab.tps b/source/expectations/data_values/ut_cursor_column_tab.tps
index 106023d96..169ba3ce4 100644
--- a/source/expectations/data_values/ut_cursor_column_tab.tps
+++ b/source/expectations/data_values/ut_cursor_column_tab.tps
@@ -1,7 +1,7 @@
-create or replace type ut_cursor_column_tab as
+create or replace noneditionable type ut_cursor_column_tab as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_cursor_details.tpb b/source/expectations/data_values/ut_cursor_details.tpb
index adc705f65..ff204e3bd 100644
--- a/source/expectations/data_values/ut_cursor_details.tpb
+++ b/source/expectations/data_values/ut_cursor_details.tpb
@@ -1,4 +1,21 @@
-create or replace type body ut_cursor_details as
+create or replace noneditionable type body ut_cursor_details as
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
member function equals( a_other ut_cursor_details, a_match_options ut_matcher_options ) return boolean is
l_diffs integer;
@@ -91,7 +108,11 @@ create or replace type body ut_cursor_details as
a_cursor_number in number
) return self as result is
l_columns_count pls_integer;
+ $if dbms_db_version.version = 12 and dbms_db_version.release = 1 or dbms_db_version.version < 12 $then
l_columns_desc dbms_sql.desc_tab3;
+ $else
+ l_columns_desc dbms_sql.desc_tab4;
+ $end
l_is_collection boolean;
l_hierarchy_level integer := 1;
begin
diff --git a/source/expectations/data_values/ut_cursor_details.tps b/source/expectations/data_values/ut_cursor_details.tps
index e7f9405eb..c50ed16d3 100644
--- a/source/expectations/data_values/ut_cursor_details.tps
+++ b/source/expectations/data_values/ut_cursor_details.tps
@@ -1,7 +1,7 @@
-create or replace type ut_cursor_details authid current_user as object (
+create or replace noneditionable type ut_cursor_details authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value.tpb b/source/expectations/data_values/ut_data_value.tpb
index 6b1763dd0..05eb3022e 100644
--- a/source/expectations/data_values/ut_data_value.tpb
+++ b/source/expectations/data_values/ut_data_value.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value as
+create or replace noneditionable type body ut_data_value as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value.tps b/source/expectations/data_values/ut_data_value.tps
index beda3d911..6e362a56d 100644
--- a/source/expectations/data_values/ut_data_value.tps
+++ b/source/expectations/data_values/ut_data_value.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value force authid current_user as object (
+create or replace noneditionable type ut_data_value force authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_anydata.tpb b/source/expectations/data_values/ut_data_value_anydata.tpb
index f6fbdc840..9fccb7582 100644
--- a/source/expectations/data_values/ut_data_value_anydata.tpb
+++ b/source/expectations/data_values/ut_data_value_anydata.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_anydata as
+create or replace noneditionable type body ut_data_value_anydata as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_anydata.tps b/source/expectations/data_values/ut_data_value_anydata.tps
index 60dba5515..6ad692d31 100644
--- a/source/expectations/data_values/ut_data_value_anydata.tps
+++ b/source/expectations/data_values/ut_data_value_anydata.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_anydata under ut_data_value_refcursor(
+create or replace noneditionable type ut_data_value_anydata under ut_data_value_refcursor(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_blob.tpb b/source/expectations/data_values/ut_data_value_blob.tpb
index e145a8d4f..c961ebaab 100644
--- a/source/expectations/data_values/ut_data_value_blob.tpb
+++ b/source/expectations/data_values/ut_data_value_blob.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_blob as
+create or replace noneditionable type body ut_data_value_blob as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_blob.tps b/source/expectations/data_values/ut_data_value_blob.tps
index 6df3f3273..94124bfec 100644
--- a/source/expectations/data_values/ut_data_value_blob.tps
+++ b/source/expectations/data_values/ut_data_value_blob.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_blob under ut_data_value(
+create or replace noneditionable type ut_data_value_blob under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_boolean.tpb b/source/expectations/data_values/ut_data_value_boolean.tpb
index 867c3c19c..dd253442c 100644
--- a/source/expectations/data_values/ut_data_value_boolean.tpb
+++ b/source/expectations/data_values/ut_data_value_boolean.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_boolean as
+create or replace noneditionable type body ut_data_value_boolean as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_boolean.tps b/source/expectations/data_values/ut_data_value_boolean.tps
index e25b6e0fd..b6df4e0b4 100644
--- a/source/expectations/data_values/ut_data_value_boolean.tps
+++ b/source/expectations/data_values/ut_data_value_boolean.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_boolean under ut_data_value(
+create or replace noneditionable type ut_data_value_boolean under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_clob.tpb b/source/expectations/data_values/ut_data_value_clob.tpb
index f8a53a035..76a55545e 100644
--- a/source/expectations/data_values/ut_data_value_clob.tpb
+++ b/source/expectations/data_values/ut_data_value_clob.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_clob as
+create or replace noneditionable type body ut_data_value_clob as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_clob.tps b/source/expectations/data_values/ut_data_value_clob.tps
index 6869798d1..686757e85 100644
--- a/source/expectations/data_values/ut_data_value_clob.tps
+++ b/source/expectations/data_values/ut_data_value_clob.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_clob under ut_data_value(
+create or replace noneditionable type ut_data_value_clob under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_date.tpb b/source/expectations/data_values/ut_data_value_date.tpb
index 20424d193..2a1232a1c 100644
--- a/source/expectations/data_values/ut_data_value_date.tpb
+++ b/source/expectations/data_values/ut_data_value_date.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_date as
+create or replace noneditionable type body ut_data_value_date as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_date.tps b/source/expectations/data_values/ut_data_value_date.tps
index f64a577e0..0bb9a17cf 100644
--- a/source/expectations/data_values/ut_data_value_date.tps
+++ b/source/expectations/data_values/ut_data_value_date.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_date under ut_data_value(
+create or replace noneditionable type ut_data_value_date under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_dsinterval.tpb b/source/expectations/data_values/ut_data_value_dsinterval.tpb
index 026d4970f..adad0ef6d 100644
--- a/source/expectations/data_values/ut_data_value_dsinterval.tpb
+++ b/source/expectations/data_values/ut_data_value_dsinterval.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_dsinterval as
+create or replace noneditionable type body ut_data_value_dsinterval as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_dsinterval.tps b/source/expectations/data_values/ut_data_value_dsinterval.tps
index 6f5cb708c..3d15e2e09 100644
--- a/source/expectations/data_values/ut_data_value_dsinterval.tps
+++ b/source/expectations/data_values/ut_data_value_dsinterval.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_dsinterval under ut_data_value(
+create or replace noneditionable type ut_data_value_dsinterval under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_json.tpb b/source/expectations/data_values/ut_data_value_json.tpb
index b703af181..e1b5aa995 100644
--- a/source/expectations/data_values/ut_data_value_json.tpb
+++ b/source/expectations/data_values/ut_data_value_json.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_json as
+create or replace noneditionable type body ut_data_value_json as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_json.tps b/source/expectations/data_values/ut_data_value_json.tps
index 3b77e54eb..c89088564 100644
--- a/source/expectations/data_values/ut_data_value_json.tps
+++ b/source/expectations/data_values/ut_data_value_json.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_json under ut_compound_data_value(
+create or replace noneditionable type ut_data_value_json under ut_compound_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_number.tpb b/source/expectations/data_values/ut_data_value_number.tpb
index 382e6e9aa..3ea08bbd4 100644
--- a/source/expectations/data_values/ut_data_value_number.tpb
+++ b/source/expectations/data_values/ut_data_value_number.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_number as
+create or replace noneditionable type body ut_data_value_number as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_number.tps b/source/expectations/data_values/ut_data_value_number.tps
index 86d68f356..e7031de72 100644
--- a/source/expectations/data_values/ut_data_value_number.tps
+++ b/source/expectations/data_values/ut_data_value_number.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_number under ut_data_value(
+create or replace noneditionable type ut_data_value_number under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_refcursor.tpb b/source/expectations/data_values/ut_data_value_refcursor.tpb
index a4f0cf7a0..b7f79ac52 100644
--- a/source/expectations/data_values/ut_data_value_refcursor.tpb
+++ b/source/expectations/data_values/ut_data_value_refcursor.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_refcursor as
+create or replace noneditionable type body ut_data_value_refcursor as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_refcursor.tps b/source/expectations/data_values/ut_data_value_refcursor.tps
index 594695e32..90a305d32 100644
--- a/source/expectations/data_values/ut_data_value_refcursor.tps
+++ b/source/expectations/data_values/ut_data_value_refcursor.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_refcursor under ut_compound_data_value(
+create or replace noneditionable type ut_data_value_refcursor under ut_compound_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp.tpb b/source/expectations/data_values/ut_data_value_timestamp.tpb
index 318f799a3..c6aabf7a3 100644
--- a/source/expectations/data_values/ut_data_value_timestamp.tpb
+++ b/source/expectations/data_values/ut_data_value_timestamp.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_timestamp as
+create or replace noneditionable type body ut_data_value_timestamp as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp.tps b/source/expectations/data_values/ut_data_value_timestamp.tps
index c047e3c79..938b0d63c 100644
--- a/source/expectations/data_values/ut_data_value_timestamp.tps
+++ b/source/expectations/data_values/ut_data_value_timestamp.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_timestamp under ut_data_value(
+create or replace noneditionable type ut_data_value_timestamp under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb b/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb
index 6127de5f1..025314f4b 100644
--- a/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb
+++ b/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_timestamp_ltz as
+create or replace noneditionable type body ut_data_value_timestamp_ltz as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp_ltz.tps b/source/expectations/data_values/ut_data_value_timestamp_ltz.tps
index 7bb296bc9..e7c61a878 100644
--- a/source/expectations/data_values/ut_data_value_timestamp_ltz.tps
+++ b/source/expectations/data_values/ut_data_value_timestamp_ltz.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_timestamp_ltz under ut_data_value(
+create or replace noneditionable type ut_data_value_timestamp_ltz under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp_tz.tpb b/source/expectations/data_values/ut_data_value_timestamp_tz.tpb
index d5d5cdd13..6af5fea4d 100644
--- a/source/expectations/data_values/ut_data_value_timestamp_tz.tpb
+++ b/source/expectations/data_values/ut_data_value_timestamp_tz.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_timestamp_tz as
+create or replace noneditionable type body ut_data_value_timestamp_tz as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp_tz.tps b/source/expectations/data_values/ut_data_value_timestamp_tz.tps
index 01cf11124..ad190d197 100644
--- a/source/expectations/data_values/ut_data_value_timestamp_tz.tps
+++ b/source/expectations/data_values/ut_data_value_timestamp_tz.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_timestamp_tz under ut_data_value(
+create or replace noneditionable type ut_data_value_timestamp_tz under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_varchar2.tpb b/source/expectations/data_values/ut_data_value_varchar2.tpb
index d04398697..7a26d7571 100644
--- a/source/expectations/data_values/ut_data_value_varchar2.tpb
+++ b/source/expectations/data_values/ut_data_value_varchar2.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_varchar2 as
+create or replace noneditionable type body ut_data_value_varchar2 as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_varchar2.tps b/source/expectations/data_values/ut_data_value_varchar2.tps
index 3fbeb378b..56effd460 100644
--- a/source/expectations/data_values/ut_data_value_varchar2.tps
+++ b/source/expectations/data_values/ut_data_value_varchar2.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_varchar2 under ut_data_value(
+create or replace noneditionable type ut_data_value_varchar2 under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_xmltype.tpb b/source/expectations/data_values/ut_data_value_xmltype.tpb
index 4b21a8937..f5ffcbc9a 100644
--- a/source/expectations/data_values/ut_data_value_xmltype.tpb
+++ b/source/expectations/data_values/ut_data_value_xmltype.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_xmltype as
+create or replace noneditionable type body ut_data_value_xmltype as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_xmltype.tps b/source/expectations/data_values/ut_data_value_xmltype.tps
index 9ba738b88..2d0257918 100644
--- a/source/expectations/data_values/ut_data_value_xmltype.tps
+++ b/source/expectations/data_values/ut_data_value_xmltype.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_xmltype under ut_data_value(
+create or replace noneditionable type ut_data_value_xmltype under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_yminterval.tpb b/source/expectations/data_values/ut_data_value_yminterval.tpb
index a3a1e7a2f..8d12d3544 100644
--- a/source/expectations/data_values/ut_data_value_yminterval.tpb
+++ b/source/expectations/data_values/ut_data_value_yminterval.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_yminterval as
+create or replace noneditionable type body ut_data_value_yminterval as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_yminterval.tps b/source/expectations/data_values/ut_data_value_yminterval.tps
index c9ad2e776..8c3ad8079 100644
--- a/source/expectations/data_values/ut_data_value_yminterval.tps
+++ b/source/expectations/data_values/ut_data_value_yminterval.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_yminterval under ut_data_value(
+create or replace noneditionable type ut_data_value_yminterval under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_json_data_diff_tmp.sql b/source/expectations/data_values/ut_json_data_diff_tmp.sql
index 5ff3440d8..4eda07d7c 100644
--- a/source/expectations/data_values/ut_json_data_diff_tmp.sql
+++ b/source/expectations/data_values/ut_json_data_diff_tmp.sql
@@ -1,7 +1,7 @@
create global temporary table ut_json_data_diff_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/expectations/data_values/ut_json_leaf.tpb b/source/expectations/data_values/ut_json_leaf.tpb
index 83f1009ef..d6c862286 100644
--- a/source/expectations/data_values/ut_json_leaf.tpb
+++ b/source/expectations/data_values/ut_json_leaf.tpb
@@ -1,5 +1,21 @@
-create or replace type body ut_json_leaf as
-
+create or replace noneditionable type body ut_json_leaf as
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
member procedure init( self in out nocopy ut_json_leaf,
a_element_name varchar2, a_element_value varchar2,a_parent_name varchar2,
a_access_path varchar2, a_hierarchy_level integer, a_index_position integer, a_json_type in varchar2,
diff --git a/source/expectations/data_values/ut_json_leaf.tps b/source/expectations/data_values/ut_json_leaf.tps
index 8aa8afd6a..ac478e34e 100644
--- a/source/expectations/data_values/ut_json_leaf.tps
+++ b/source/expectations/data_values/ut_json_leaf.tps
@@ -1,7 +1,7 @@
-create or replace type ut_json_leaf authid current_user as object (
+create or replace noneditionable type ut_json_leaf authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_json_leaf_tab.tps b/source/expectations/data_values/ut_json_leaf_tab.tps
index 395ab5d9e..c00f2a3a1 100644
--- a/source/expectations/data_values/ut_json_leaf_tab.tps
+++ b/source/expectations/data_values/ut_json_leaf_tab.tps
@@ -1,7 +1,7 @@
-create or replace type ut_json_leaf_tab as
+create or replace noneditionable type ut_json_leaf_tab as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_json_tree_details.tpb b/source/expectations/data_values/ut_json_tree_details.tpb
index a333ea71c..0d457b2c5 100644
--- a/source/expectations/data_values/ut_json_tree_details.tpb
+++ b/source/expectations/data_values/ut_json_tree_details.tpb
@@ -1,4 +1,20 @@
-create or replace type body ut_json_tree_details as
+create or replace noneditionable type body ut_json_tree_details as
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
member function get_json_type(a_json_piece json_element_t) return varchar2 is
begin
diff --git a/source/expectations/data_values/ut_json_tree_details.tps b/source/expectations/data_values/ut_json_tree_details.tps
index 20ac2fdcc..4f7e891be 100644
--- a/source/expectations/data_values/ut_json_tree_details.tps
+++ b/source/expectations/data_values/ut_json_tree_details.tps
@@ -1,7 +1,7 @@
-create or replace type ut_json_tree_details force as object (
+create or replace noneditionable type ut_json_tree_details force as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_key_anyval_pair.tps b/source/expectations/data_values/ut_key_anyval_pair.tps
index d1068f109..6ed63ae7e 100644
--- a/source/expectations/data_values/ut_key_anyval_pair.tps
+++ b/source/expectations/data_values/ut_key_anyval_pair.tps
@@ -1,7 +1,7 @@
-create or replace type ut_key_anyval_pair force as object(
+create or replace noneditionable type ut_key_anyval_pair force as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_key_anyval_pairs.tps b/source/expectations/data_values/ut_key_anyval_pairs.tps
index 7e10bf50f..a75305f79 100644
--- a/source/expectations/data_values/ut_key_anyval_pairs.tps
+++ b/source/expectations/data_values/ut_key_anyval_pairs.tps
@@ -1,7 +1,7 @@
-create or replace type ut_key_anyval_pairs as
+create or replace noneditionable type ut_key_anyval_pairs as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_key_anyvalues.tpb b/source/expectations/data_values/ut_key_anyvalues.tpb
index d30d8a841..4e6dd2c0f 100644
--- a/source/expectations/data_values/ut_key_anyvalues.tpb
+++ b/source/expectations/data_values/ut_key_anyvalues.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_key_anyvalues as
+create or replace noneditionable type body ut_key_anyvalues as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_key_anyvalues.tps b/source/expectations/data_values/ut_key_anyvalues.tps
index 8c672bd00..21a9a5c72 100644
--- a/source/expectations/data_values/ut_key_anyvalues.tps
+++ b/source/expectations/data_values/ut_key_anyvalues.tps
@@ -1,7 +1,7 @@
-create or replace type ut_key_anyvalues under ut_event_item (
+create or replace noneditionable type ut_key_anyvalues under ut_event_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/json_objects_specs.sql b/source/expectations/json_objects_specs.sql
index a5d936afb..c0fc15ed6 100644
--- a/source/expectations/json_objects_specs.sql
+++ b/source/expectations/json_objects_specs.sql
@@ -2,13 +2,13 @@ BEGIN
null;
$if dbms_db_version.version < 21 $then
dbms_output.put_line('Installing json structures specs for native json.');
- execute immediate q'[create or replace TYPE JSON FORCE AUTHID CURRENT_USER AS OBJECT(
+ execute immediate q'[create or replace noneditionable TYPE JSON FORCE AUTHID CURRENT_USER AS OBJECT(
dummyobjt NUMBER
) NOT FINAL NOT INSTANTIABLE;]';
$end
$if dbms_db_version.version = 12 and dbms_db_version.release = 1 or dbms_db_version.version < 12 $then
dbms_output.put_line('Installing json structures specs.');
- execute immediate q'[create or replace TYPE JSON_Element_T FORCE AUTHID CURRENT_USER AS OBJECT(
+ execute immediate q'[create or replace noneditionable TYPE JSON_Element_T FORCE AUTHID CURRENT_USER AS OBJECT(
dummyobjt NUMBER,
STATIC FUNCTION parse(jsn VARCHAR2) RETURN JSON_Element_T,
STATIC FUNCTION parse(jsn CLOB) RETURN JSON_Element_T,
@@ -34,9 +34,9 @@ BEGIN
MEMBER FUNCTION get_Size(self IN JSON_ELEMENT_T) RETURN NUMBER
) NOT FINAL NOT INSTANTIABLE;]';
- execute immediate q'[create or replace TYPE JSON_KEY_LIST FORCE AS VARRAY(32767) OF VARCHAR2(4000);]';
+ execute immediate q'[create or replace noneditionable TYPE JSON_KEY_LIST FORCE AS VARRAY(32767) OF VARCHAR2(4000);]';
- execute immediate q'[create or replace TYPE JSON_Array_T FORCE AUTHID CURRENT_USER UNDER JSON_Element_T(
+ execute immediate q'[create or replace noneditionable TYPE JSON_Array_T FORCE AUTHID CURRENT_USER UNDER JSON_Element_T(
CONSTRUCTOR FUNCTION JSON_Array_T RETURN SELF AS RESULT,
MEMBER FUNCTION get(pos NUMBER) RETURN JSON_Element_T,
MEMBER FUNCTION get_String(pos NUMBER) RETURN VARCHAR2,
@@ -51,7 +51,7 @@ BEGIN
MEMBER FUNCTION get_Type(pos NUMBER) RETURN VARCHAR2
) FINAL;]';
- execute immediate q'[create or replace TYPE JSON_Object_T AUTHID CURRENT_USER UNDER JSON_Element_T(
+ execute immediate q'[create or replace noneditionable TYPE JSON_Object_T AUTHID CURRENT_USER UNDER JSON_Element_T(
CONSTRUCTOR FUNCTION JSON_Object_T RETURN SELF AS RESULT,
MEMBER FUNCTION get(key VARCHAR2) RETURN JSON_Element_T,
MEMBER FUNCTION get_Object(key VARCHAR2) RETURN JSON_OBJECT_T,
diff --git a/source/expectations/matchers/ut_be_between.tpb b/source/expectations/matchers/ut_be_between.tpb
index 6aea96f55..83dfc4c25 100644
--- a/source/expectations/matchers/ut_be_between.tpb
+++ b/source/expectations/matchers/ut_be_between.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_between is
+create or replace noneditionable type body ut_be_between is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_between.tps b/source/expectations/matchers/ut_be_between.tps
index 9e984085b..7f1403847 100644
--- a/source/expectations/matchers/ut_be_between.tps
+++ b/source/expectations/matchers/ut_be_between.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_between under ut_matcher(
+create or replace noneditionable type ut_be_between under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_empty.tpb b/source/expectations/matchers/ut_be_empty.tpb
index e5e02f6b2..af233aa8f 100644
--- a/source/expectations/matchers/ut_be_empty.tpb
+++ b/source/expectations/matchers/ut_be_empty.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_empty as
+create or replace noneditionable type body ut_be_empty as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_empty.tps b/source/expectations/matchers/ut_be_empty.tps
index 9e9f899d0..a5672ba78 100644
--- a/source/expectations/matchers/ut_be_empty.tps
+++ b/source/expectations/matchers/ut_be_empty.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_empty under ut_matcher(
+create or replace noneditionable type ut_be_empty under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_false.tpb b/source/expectations/matchers/ut_be_false.tpb
index 4cc88600a..a02ac58cb 100644
--- a/source/expectations/matchers/ut_be_false.tpb
+++ b/source/expectations/matchers/ut_be_false.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_false as
+create or replace noneditionable type body ut_be_false as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_false.tps b/source/expectations/matchers/ut_be_false.tps
index ede510719..d793844c1 100644
--- a/source/expectations/matchers/ut_be_false.tps
+++ b/source/expectations/matchers/ut_be_false.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_false under ut_matcher(
+create or replace noneditionable type ut_be_false under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_greater_or_equal.tpb b/source/expectations/matchers/ut_be_greater_or_equal.tpb
index 1c2a19c09..6e564a90c 100644
--- a/source/expectations/matchers/ut_be_greater_or_equal.tpb
+++ b/source/expectations/matchers/ut_be_greater_or_equal.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_greater_or_equal AS
+create or replace noneditionable type body ut_be_greater_or_equal AS
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_greater_or_equal.tps b/source/expectations/matchers/ut_be_greater_or_equal.tps
index b3ab54ff1..d3e651958 100644
--- a/source/expectations/matchers/ut_be_greater_or_equal.tps
+++ b/source/expectations/matchers/ut_be_greater_or_equal.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_greater_or_equal under ut_comparison_matcher(
+create or replace noneditionable type ut_be_greater_or_equal under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_greater_than.tpb b/source/expectations/matchers/ut_be_greater_than.tpb
index 9cce79119..08628ae3a 100644
--- a/source/expectations/matchers/ut_be_greater_than.tpb
+++ b/source/expectations/matchers/ut_be_greater_than.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_greater_than AS
+create or replace noneditionable type body ut_be_greater_than AS
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_greater_than.tps b/source/expectations/matchers/ut_be_greater_than.tps
index a5a44692d..745b19f08 100644
--- a/source/expectations/matchers/ut_be_greater_than.tps
+++ b/source/expectations/matchers/ut_be_greater_than.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_greater_than under ut_comparison_matcher(
+create or replace noneditionable type ut_be_greater_than under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_less_or_equal.tpb b/source/expectations/matchers/ut_be_less_or_equal.tpb
index 6acec1dda..2df06a078 100644
--- a/source/expectations/matchers/ut_be_less_or_equal.tpb
+++ b/source/expectations/matchers/ut_be_less_or_equal.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_less_or_equal AS
+create or replace noneditionable type body ut_be_less_or_equal AS
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_less_or_equal.tps b/source/expectations/matchers/ut_be_less_or_equal.tps
index 118611a41..f0e297ad1 100644
--- a/source/expectations/matchers/ut_be_less_or_equal.tps
+++ b/source/expectations/matchers/ut_be_less_or_equal.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_less_or_equal under ut_comparison_matcher(
+create or replace noneditionable type ut_be_less_or_equal under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_less_than.tpb b/source/expectations/matchers/ut_be_less_than.tpb
index 7608e4917..c0b059231 100644
--- a/source/expectations/matchers/ut_be_less_than.tpb
+++ b/source/expectations/matchers/ut_be_less_than.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_less_than as
+create or replace noneditionable type body ut_be_less_than as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_less_than.tps b/source/expectations/matchers/ut_be_less_than.tps
index b652de789..594df9b71 100644
--- a/source/expectations/matchers/ut_be_less_than.tps
+++ b/source/expectations/matchers/ut_be_less_than.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_less_than under ut_comparison_matcher(
+create or replace noneditionable type ut_be_less_than under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_like.tpb b/source/expectations/matchers/ut_be_like.tpb
index 6865c2942..b94c3fa91 100644
--- a/source/expectations/matchers/ut_be_like.tpb
+++ b/source/expectations/matchers/ut_be_like.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_like as
+create or replace noneditionable type body ut_be_like as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_like.tps b/source/expectations/matchers/ut_be_like.tps
index dae93a1d9..ca9ad45de 100644
--- a/source/expectations/matchers/ut_be_like.tps
+++ b/source/expectations/matchers/ut_be_like.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_like under ut_matcher(
+create or replace noneditionable type ut_be_like under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_not_null.tpb b/source/expectations/matchers/ut_be_not_null.tpb
index 194e2ea32..d291d2e35 100644
--- a/source/expectations/matchers/ut_be_not_null.tpb
+++ b/source/expectations/matchers/ut_be_not_null.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_not_null as
+create or replace noneditionable type body ut_be_not_null as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_not_null.tps b/source/expectations/matchers/ut_be_not_null.tps
index 196aac9fb..61f6c871d 100644
--- a/source/expectations/matchers/ut_be_not_null.tps
+++ b/source/expectations/matchers/ut_be_not_null.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_not_null under ut_matcher(
+create or replace noneditionable type ut_be_not_null under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_null.tpb b/source/expectations/matchers/ut_be_null.tpb
index 8c672791b..89fbaf563 100644
--- a/source/expectations/matchers/ut_be_null.tpb
+++ b/source/expectations/matchers/ut_be_null.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_null as
+create or replace noneditionable type body ut_be_null as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_null.tps b/source/expectations/matchers/ut_be_null.tps
index 3b2d6ac84..063c7db29 100644
--- a/source/expectations/matchers/ut_be_null.tps
+++ b/source/expectations/matchers/ut_be_null.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_null under ut_matcher(
+create or replace noneditionable type ut_be_null under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_true.tpb b/source/expectations/matchers/ut_be_true.tpb
index fe78b4e22..59368f342 100644
--- a/source/expectations/matchers/ut_be_true.tpb
+++ b/source/expectations/matchers/ut_be_true.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_true as
+create or replace noneditionable type body ut_be_true as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_true.tps b/source/expectations/matchers/ut_be_true.tps
index 8b5491e39..19d397371 100644
--- a/source/expectations/matchers/ut_be_true.tps
+++ b/source/expectations/matchers/ut_be_true.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_true under ut_matcher(
+create or replace noneditionable type ut_be_true under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within.tpb b/source/expectations/matchers/ut_be_within.tpb
index e2aa792d0..f8f880ace 100644
--- a/source/expectations/matchers/ut_be_within.tpb
+++ b/source/expectations/matchers/ut_be_within.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_within as
+create or replace noneditionable type body ut_be_within as
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within.tps b/source/expectations/matchers/ut_be_within.tps
index 576f9ff37..276c529df 100644
--- a/source/expectations/matchers/ut_be_within.tps
+++ b/source/expectations/matchers/ut_be_within.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_within force under ut_be_within_pct(
+create or replace noneditionable type ut_be_within force under ut_be_within_pct(
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within_helper.pkb b/source/expectations/matchers/ut_be_within_helper.pkb
index 5dd82baa2..635c1b111 100644
--- a/source/expectations/matchers/ut_be_within_helper.pkb
+++ b/source/expectations/matchers/ut_be_within_helper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_be_within_helper as
+create or replace noneditionable package body ut_be_within_helper as
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within_helper.pks b/source/expectations/matchers/ut_be_within_helper.pks
index 41737cc8f..5a59eea9e 100644
--- a/source/expectations/matchers/ut_be_within_helper.pks
+++ b/source/expectations/matchers/ut_be_within_helper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_be_within_helper authid definer as
+create or replace noneditionable package ut_be_within_helper authid definer as
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within_pct.tpb b/source/expectations/matchers/ut_be_within_pct.tpb
index 8b280ffff..82ce8e84e 100644
--- a/source/expectations/matchers/ut_be_within_pct.tpb
+++ b/source/expectations/matchers/ut_be_within_pct.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_within_pct as
+create or replace noneditionable type body ut_be_within_pct as
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within_pct.tps b/source/expectations/matchers/ut_be_within_pct.tps
index 499e9a2d8..810eaa5b3 100644
--- a/source/expectations/matchers/ut_be_within_pct.tps
+++ b/source/expectations/matchers/ut_be_within_pct.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_within_pct force under ut_comparison_matcher(
+create or replace noneditionable type ut_be_within_pct force under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@ create or replace type ut_be_within_pct force under ut_comparison_matcher(
limitations under the License.
*/
-
/**
* Holds information about mather options
*/
diff --git a/source/expectations/matchers/ut_comparison_matcher.tpb b/source/expectations/matchers/ut_comparison_matcher.tpb
index 20ed35927..d6c47855d 100644
--- a/source/expectations/matchers/ut_comparison_matcher.tpb
+++ b/source/expectations/matchers/ut_comparison_matcher.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_comparison_matcher as
+create or replace noneditionable type body ut_comparison_matcher as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_comparison_matcher.tps b/source/expectations/matchers/ut_comparison_matcher.tps
index 68ecb4462..b1ed08a84 100644
--- a/source/expectations/matchers/ut_comparison_matcher.tps
+++ b/source/expectations/matchers/ut_comparison_matcher.tps
@@ -1,7 +1,7 @@
-create or replace type ut_comparison_matcher under ut_matcher(
+create or replace noneditionable type ut_comparison_matcher under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_contain.tpb b/source/expectations/matchers/ut_contain.tpb
index 7591925f5..bcc3806b7 100644
--- a/source/expectations/matchers/ut_contain.tpb
+++ b/source/expectations/matchers/ut_contain.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_contain as
+create or replace noneditionable type body ut_contain as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -47,6 +47,7 @@ create or replace type body ut_contain as
overriding member function run_matcher_negated(self in out nocopy ut_contain, a_actual ut_data_value) return boolean is
begin
+ self.negated();
return run_matcher(a_actual);
end;
diff --git a/source/expectations/matchers/ut_contain.tps b/source/expectations/matchers/ut_contain.tps
index e572edf62..bd67113c9 100644
--- a/source/expectations/matchers/ut_contain.tps
+++ b/source/expectations/matchers/ut_contain.tps
@@ -1,7 +1,7 @@
-create or replace type ut_contain under ut_equal(
+create or replace noneditionable type ut_contain under ut_equal(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_equal.tpb b/source/expectations/matchers/ut_equal.tpb
index d514e34d0..f999995d1 100644
--- a/source/expectations/matchers/ut_equal.tpb
+++ b/source/expectations/matchers/ut_equal.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_equal as
+create or replace noneditionable type body ut_equal as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_equal.tps b/source/expectations/matchers/ut_equal.tps
index e48b797ed..eeb715a58 100644
--- a/source/expectations/matchers/ut_equal.tps
+++ b/source/expectations/matchers/ut_equal.tps
@@ -1,7 +1,7 @@
-create or replace type ut_equal force under ut_comparison_matcher(
+create or replace noneditionable type ut_equal force under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_have_count.tpb b/source/expectations/matchers/ut_have_count.tpb
index 457cd6272..f6d3d2682 100644
--- a/source/expectations/matchers/ut_have_count.tpb
+++ b/source/expectations/matchers/ut_have_count.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_have_count as
+create or replace noneditionable type body ut_have_count as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_have_count.tps b/source/expectations/matchers/ut_have_count.tps
index d48dc44c8..85cdf4393 100644
--- a/source/expectations/matchers/ut_have_count.tps
+++ b/source/expectations/matchers/ut_have_count.tps
@@ -1,7 +1,7 @@
-create or replace type ut_have_count under ut_matcher(
+create or replace noneditionable type ut_have_count under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_match.tpb b/source/expectations/matchers/ut_match.tpb
index 3c7a71402..1836298e7 100644
--- a/source/expectations/matchers/ut_match.tpb
+++ b/source/expectations/matchers/ut_match.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_match as
+create or replace noneditionable type body ut_match as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_match.tps b/source/expectations/matchers/ut_match.tps
index ee51a4c28..3f840545f 100644
--- a/source/expectations/matchers/ut_match.tps
+++ b/source/expectations/matchers/ut_match.tps
@@ -1,7 +1,7 @@
-create or replace type ut_match under ut_matcher(
+create or replace noneditionable type ut_match under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher.tpb b/source/expectations/matchers/ut_matcher.tpb
index 6b5b98465..828e1ac51 100644
--- a/source/expectations/matchers/ut_matcher.tpb
+++ b/source/expectations/matchers/ut_matcher.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_matcher as
+create or replace noneditionable type body ut_matcher as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher.tps b/source/expectations/matchers/ut_matcher.tps
index a034e4ed2..ee7f1b5dd 100644
--- a/source/expectations/matchers/ut_matcher.tps
+++ b/source/expectations/matchers/ut_matcher.tps
@@ -1,7 +1,7 @@
-create or replace type ut_matcher under ut_matcher_base(
+create or replace noneditionable type ut_matcher under ut_matcher_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher_base.tps b/source/expectations/matchers/ut_matcher_base.tps
index ef7fd98a2..ba79a6aed 100644
--- a/source/expectations/matchers/ut_matcher_base.tps
+++ b/source/expectations/matchers/ut_matcher_base.tps
@@ -1,4 +1,21 @@
-create or replace type ut_matcher_base force authid current_user as object(
+create or replace noneditionable type ut_matcher_base force authid current_user as object(
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
self_type varchar2(250)
)
not final not instantiable
diff --git a/source/expectations/matchers/ut_matcher_options.tpb b/source/expectations/matchers/ut_matcher_options.tpb
index 8730c204b..57aca2617 100644
--- a/source/expectations/matchers/ut_matcher_options.tpb
+++ b/source/expectations/matchers/ut_matcher_options.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_matcher_options as
+create or replace noneditionable type body ut_matcher_options as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher_options.tps b/source/expectations/matchers/ut_matcher_options.tps
index 276cad2ec..db076fd99 100644
--- a/source/expectations/matchers/ut_matcher_options.tps
+++ b/source/expectations/matchers/ut_matcher_options.tps
@@ -1,7 +1,7 @@
-create or replace type ut_matcher_options authid current_user as object(
+create or replace noneditionable type ut_matcher_options authid current_user as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher_options_items.tpb b/source/expectations/matchers/ut_matcher_options_items.tpb
index 92da588ce..6e4841870 100644
--- a/source/expectations/matchers/ut_matcher_options_items.tpb
+++ b/source/expectations/matchers/ut_matcher_options_items.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_matcher_options_items is
+create or replace noneditionable type body ut_matcher_options_items is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher_options_items.tps b/source/expectations/matchers/ut_matcher_options_items.tps
index 53787070d..045a7ece7 100644
--- a/source/expectations/matchers/ut_matcher_options_items.tps
+++ b/source/expectations/matchers/ut_matcher_options_items.tps
@@ -1,7 +1,7 @@
-create or replace type ut_matcher_options_items authid current_user as object(
+create or replace noneditionable type ut_matcher_options_items authid current_user as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/ut_expectation.tpb b/source/expectations/ut_expectation.tpb
index a78c57eb7..5f7c9cce0 100644
--- a/source/expectations/ut_expectation.tpb
+++ b/source/expectations/ut_expectation.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_expectation as
+create or replace noneditionable type body ut_expectation as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -686,7 +686,7 @@ create or replace type body ut_expectation as
member procedure not_to_contain(self in ut_expectation, a_expected sys_refcursor) is
begin
- self.not_to( ut_contain(a_expected).negated() );
+ self.not_to( ut_contain(a_expected));
end;
member procedure to_contain(self in ut_expectation, a_expected anydata) is
@@ -696,7 +696,7 @@ create or replace type body ut_expectation as
member procedure not_to_contain(self in ut_expectation, a_expected anydata) is
begin
- self.not_to( ut_contain(a_expected).negated() );
+ self.not_to( ut_contain(a_expected));
end;
member function to_be_within(a_dist number) return ut_be_within is
diff --git a/source/expectations/ut_expectation.tps b/source/expectations/ut_expectation.tps
index 30fe985d3..a423c39a4 100644
--- a/source/expectations/ut_expectation.tps
+++ b/source/expectations/ut_expectation.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation force under ut_expectation_base(
+create or replace noneditionable type ut_expectation force under ut_expectation_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/ut_expectation_base.tpb b/source/expectations/ut_expectation_base.tpb
index 20b3e7a95..5ed630c63 100644
--- a/source/expectations/ut_expectation_base.tpb
+++ b/source/expectations/ut_expectation_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_expectation_base as
+create or replace noneditionable type body ut_expectation_base as
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@ create or replace type body ut_expectation_base as
See the License for the specific language governing permissions and
limitations under the License.
*/
+
member procedure to_(self in ut_expectation_base, a_matcher ut_matcher_base) is
l_expectation_result boolean;
l_matcher ut_matcher := treat(a_matcher as ut_matcher);
diff --git a/source/expectations/ut_expectation_base.tps b/source/expectations/ut_expectation_base.tps
index a542d26ea..86f274495 100644
--- a/source/expectations/ut_expectation_base.tps
+++ b/source/expectations/ut_expectation_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation_base authid current_user as object(
+create or replace noneditionable type ut_expectation_base authid current_user as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@ create or replace type ut_expectation_base authid current_user as object(
See the License for the specific language governing permissions and
limitations under the License.
*/
+
actual_data ut_data_value,
description varchar2(4000 char),
diff --git a/source/expectations/ut_expectation_compound.tpb b/source/expectations/ut_expectation_compound.tpb
index 6fc2e2647..d76010f80 100644
--- a/source/expectations/ut_expectation_compound.tpb
+++ b/source/expectations/ut_expectation_compound.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_expectation_compound as
+create or replace noneditionable type body ut_expectation_compound as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/ut_expectation_compound.tps b/source/expectations/ut_expectation_compound.tps
index 46da23fea..54de48dd4 100644
--- a/source/expectations/ut_expectation_compound.tps
+++ b/source/expectations/ut_expectation_compound.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation_compound under ut_expectation(
+create or replace noneditionable type ut_expectation_compound under ut_expectation(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/ut_expectation_json.tpb b/source/expectations/ut_expectation_json.tpb
index b71e8ea83..68d4085ef 100644
--- a/source/expectations/ut_expectation_json.tpb
+++ b/source/expectations/ut_expectation_json.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_expectation_json as
+create or replace noneditionable type body ut_expectation_json as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/ut_expectation_json.tps b/source/expectations/ut_expectation_json.tps
index 561c5d11f..c75154bc8 100644
--- a/source/expectations/ut_expectation_json.tps
+++ b/source/expectations/ut_expectation_json.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation_json under ut_expectation(
+create or replace noneditionable type ut_expectation_json under ut_expectation(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/install.sql b/source/install.sql
index 6f3c16801..9af0a4f66 100644
--- a/source/install.sql
+++ b/source/install.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -50,6 +50,8 @@ create or replace context &&ut3_owner._info using &&ut3_owner..ut_session_contex
@@install_component.sql 'core/types/ut_key_value_pairs.tps'
@@install_component.sql 'core/types/ut_reporter_info.tps'
@@install_component.sql 'core/types/ut_reporters_info.tps'
+@@install_component.sql 'core/types/ut_stack.tps'
+@@install_component.sql 'core/types/ut_stack.tpb'
@@install_component.sql 'core/ut_utils.pks'
@@install_component.sql 'core/ut_metadata.pks'
@@install_component.sql 'core/ut_savepoint_seq.sql'
@@ -120,6 +122,8 @@ create or replace context &&ut3_owner._info using &&ut3_owner..ut_session_contex
@@install_component.sql 'core/output_buffers/ut_output_table_buffer.tpb'
@@install_component.sql 'core/output_buffers/ut_output_clob_table_buffer.tps'
@@install_component.sql 'core/output_buffers/ut_output_clob_table_buffer.tpb'
+@@install_component.sql 'core/output_buffers/ut_output_bulk_buffer.tps'
+@@install_component.sql 'core/output_buffers/ut_output_bulk_buffer.tpb'
@@install_component.sql 'core/types/ut_output_reporter_base.tps'
@@ -151,6 +155,8 @@ create or replace context &&ut3_owner._info using &&ut3_owner..ut_session_contex
@@install_component.sql 'core/ut_suite_cache_seq.sql'
@@install_component.sql 'core/ut_suite_cache.sql'
+@@install_component.sql 'core/ut_suite_tag_filter.pks'
+@@install_component.sql 'core/ut_suite_tag_filter.pkb'
@@install_component.sql 'core/ut_suite_cache_manager.pks'
@@install_component.sql 'core/ut_suite_cache_manager.pkb'
@@install_component.sql 'core/ut_suite_builder.pks'
@@ -340,6 +346,8 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema
@@install_component.sql 'reporters/ut_xunit_reporter.tpb'
@@install_component.sql 'reporters/ut_sonar_test_reporter.tps'
@@install_component.sql 'reporters/ut_sonar_test_reporter.tpb'
+@@install_component.sql 'reporters/ut_tap_reporter.tps'
+@@install_component.sql 'reporters/ut_tap_reporter.tpb'
@@install_component.sql 'reporters/ut_coverage_html_reporter.tps'
@@install_component.sql 'reporters/ut_coverage_report_html_helper.pks'
@@ -347,8 +355,6 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema
@@install_component.sql 'reporters/ut_coverage_html_reporter.tpb'
@@install_component.sql 'reporters/ut_coverage_sonar_reporter.tps'
@@install_component.sql 'reporters/ut_coverage_sonar_reporter.tpb'
-@@install_component.sql 'reporters/ut_coveralls_reporter.tps'
-@@install_component.sql 'reporters/ut_coveralls_reporter.tpb'
@@install_component.sql 'reporters/ut_coverage_cobertura_reporter.tps'
@@install_component.sql 'reporters/ut_coverage_cobertura_reporter.tpb'
@@install_component.sql 'reporters/ut_realtime_reporter.tps'
diff --git a/source/install_above_12_1.sql b/source/install_above_12_1.sql
index 69e47ce9a..5a1943358 100644
--- a/source/install_above_12_1.sql
+++ b/source/install_above_12_1.sql
@@ -1,3 +1,20 @@
+/*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
def FILE_NAME = '&&1'
column SCRIPT_NAME new_value SCRIPT_NAME noprint
diff --git a/source/install_component.sql b/source/install_component.sql
index 373c85c54..1189df496 100644
--- a/source/install_component.sql
+++ b/source/install_component.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/install_ddl_trigger.sql b/source/install_ddl_trigger.sql
index bc147c2be..b23b4bc63 100644
--- a/source/install_ddl_trigger.sql
+++ b/source/install_ddl_trigger.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/install_headless.sql b/source/install_headless.sql
index 183262675..be1e5becf 100644
--- a/source/install_headless.sql
+++ b/source/install_headless.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/install_headless_with_trigger.sql b/source/install_headless_with_trigger.sql
index 76ae48ccb..2c05403c5 100644
--- a/source/install_headless_with_trigger.sql
+++ b/source/install_headless_with_trigger.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_ansiconsole_helper.pkb b/source/reporters/ut_ansiconsole_helper.pkb
index 53e6bc6aa..e8ee34531 100644
--- a/source/reporters/ut_ansiconsole_helper.pkb
+++ b/source/reporters/ut_ansiconsole_helper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_ansiconsole_helper as
+create or replace noneditionable package body ut_ansiconsole_helper as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_ansiconsole_helper.pks b/source/reporters/ut_ansiconsole_helper.pks
index 217d36a49..e882de293 100644
--- a/source/reporters/ut_ansiconsole_helper.pks
+++ b/source/reporters/ut_ansiconsole_helper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_ansiconsole_helper as
+create or replace noneditionable package ut_ansiconsole_helper as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_coverage_cobertura_reporter.tpb b/source/reporters/ut_coverage_cobertura_reporter.tpb
index 48082a6d4..45c1935b1 100644
--- a/source/reporters/ut_coverage_cobertura_reporter.tpb
+++ b/source/reporters/ut_coverage_cobertura_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_coverage_cobertura_reporter is
+create or replace noneditionable type body ut_coverage_cobertura_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ create or replace type body ut_coverage_cobertura_reporter is
self in out nocopy ut_coverage_cobertura_reporter
) return self as result is
begin
- self.init($$plsql_unit);
+ self.init($$plsql_unit,ut_output_bulk_buffer());
return;
end;
@@ -29,11 +29,19 @@ create or replace type body ut_coverage_cobertura_reporter is
l_report_lines ut_varchar2_list;
l_coverage_data ut_coverage.t_coverage;
- function get_lines_xml(a_unit_coverage ut_coverage.t_unit_coverage) return clob is
+ function get_line_rate(a_lines_covered in integer, a_lines_hit in integer) return varchar2 is
+ begin
+ return to_char(round((case a_lines_covered when 0 then 0 else a_lines_covered/a_lines_hit end), 17), rpad('FM0.0',20,'9') , 'NLS_NUMERIC_CHARACTERS=''. ''');
+ end;
+
+ procedure get_lines_xml(a_unit_coverage ut_coverage.t_unit_coverage,
+ a_lines_result in out nocopy clob, a_lines_hits out number, a_lines_total out number) is
l_file_part varchar2(32767);
l_result clob;
l_line_no binary_integer;
l_pct integer;
+ l_lines_hits integer := 0;
+ l_lines_total integer := 0;
begin
dbms_lob.createtemporary(l_result, true);
l_line_no := a_unit_coverage.lines.first;
@@ -41,11 +49,14 @@ create or replace type body ut_coverage_cobertura_reporter is
for i in 1 .. a_unit_coverage.total_lines loop
ut_utils.append_to_clob(l_result, ''||chr(10));
end loop;
+ l_lines_hits:=0;
+ l_lines_total:= a_unit_coverage.total_lines;
else
while l_line_no is not null loop
if a_unit_coverage.lines(l_line_no).executions = 0 then
l_file_part := ''||chr(10);
else
+ l_lines_hits:= l_lines_hits+1;
l_file_part := ''
+ ''
);
ut_utils.append_to_list(
@@ -129,13 +150,13 @@ create or replace type body ut_coverage_cobertura_reporter is
ut_utils.append_to_list(
l_result,
''
+ ||dbms_xmlgen.convert(l_unit)||'" line-rate="'||get_line_rate(l_line_hits,l_line_total)||'" branch-rate="0.0" complexity="0.0">'
);
ut_utils.append_to_list(l_result, '');
-
- ut_utils.append_to_list( l_result, get_lines_xml(a_coverage_data.objects(l_unit)) );
-
+ ut_utils.append_to_list( l_result,l_lines_xml);
+ dbms_lob.freetemporary(l_lines_xml);
+
ut_utils.append_to_list(l_result, c_lines_footer);
ut_utils.append_to_list(l_result, c_class_footer);
ut_utils.append_to_list(l_result, c_classes_footer);
diff --git a/source/reporters/ut_coverage_cobertura_reporter.tps b/source/reporters/ut_coverage_cobertura_reporter.tps
index 1292e60fb..799840a55 100644
--- a/source/reporters/ut_coverage_cobertura_reporter.tps
+++ b/source/reporters/ut_coverage_cobertura_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_coverage_cobertura_reporter under ut_coverage_reporter_base(
+create or replace noneditionable type ut_coverage_cobertura_reporter under ut_coverage_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_coverage_html_reporter.tpb b/source/reporters/ut_coverage_html_reporter.tpb
index c88c91a80..90419371a 100644
--- a/source/reporters/ut_coverage_html_reporter.tpb
+++ b/source/reporters/ut_coverage_html_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_coverage_html_reporter is
+create or replace noneditionable type body ut_coverage_html_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ create or replace type body ut_coverage_html_reporter is
a_html_report_assets_path varchar2 := null
) return self as result is
begin
- self.init($$plsql_unit);
+ self.init($$plsql_unit,ut_output_bulk_buffer());
self.project_name := a_project_name;
assets_path := nvl(a_html_report_assets_path, ut_coverage_report_html_helper.get_default_html_assets_path());
return;
diff --git a/source/reporters/ut_coverage_html_reporter.tps b/source/reporters/ut_coverage_html_reporter.tps
index 42f2fd4e3..23cf45c0b 100644
--- a/source/reporters/ut_coverage_html_reporter.tps
+++ b/source/reporters/ut_coverage_html_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_coverage_html_reporter under ut_coverage_reporter_base(
+create or replace noneditionable type ut_coverage_html_reporter under ut_coverage_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb
index 2bb9a87d9..99c36ab73 100644
--- a/source/reporters/ut_coverage_report_html_helper.pkb
+++ b/source/reporters/ut_coverage_report_html_helper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_report_html_helper is
+create or replace noneditionable package body ut_coverage_report_html_helper is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -90,7 +90,7 @@ create or replace package body ut_coverage_report_html_helper is
function object_id(a_object_full_name varchar2) return varchar2 is
begin
- return rawtohex(dbms_crypto.hash(src => utl_raw.cast_to_raw(a_object_full_name), typ => dbms_crypto.hash_md5));
+ return rawtohex(dbms_crypto.hash(src => utl_raw.cast_to_raw(a_object_full_name), typ => dbms_crypto.HASH_SH256));
end;
function link_to_source_file(a_object_full_name varchar2) return varchar2 is
@@ -134,9 +134,11 @@ create or replace package body ut_coverage_report_html_helper is
l_file_part varchar2(32767);
l_result ut_varchar2_rows := ut_varchar2_rows();
l_coverage_pct number(5, 2);
- l_coverage_block_pct number(5, 2);
l_hits varchar2(30);
l_blocks varchar2(30);
+ l_line_text varchar2(32767);
+ e_buffer_too_small exception;
+ pragma exception_init ( e_buffer_too_small, -19011 );
begin
l_coverage_pct := coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines);
@@ -148,10 +150,16 @@ create or replace package body ut_coverage_report_html_helper is
ut_utils.append_to_list(l_result, l_file_part);
for line_no in 1 .. a_source_code.count loop
+ begin
+ l_line_text := dbms_xmlgen.convert(a_source_code(line_no));
+ exception
+ when e_buffer_too_small then
+ l_line_text := dbms_xmlgen.convert(to_clob(a_source_code(line_no)));
+ end;
if not a_coverage_unit.lines.exists(line_no) then
l_file_part := '