SnowConvert AI - Top-Level Code Units Report¶
O que é uma unidade de código de nível superior?¶
Uma unidade de código, como o nome sugere, é o elemento executável mais atômico e autônomo. Na maioria dos casos, são instruções, mas também incluem arquivos de script, pois são executados como um único elemento.
Algumas unidades de código podem ser aninhadas dentro de outras unidades de código. Quando não há outra unidade de código acima dela em uma hierarquia de unidades, ela é chamada de unidade de código de nível superior.
O que é uma unidade de código fora do escopo?¶
Out-of-scope Top-Level Code Units are Code Units that are out of the conversion scope of SnowConvert AI. Because of this, these code units are not considered when calculating the conversion rate. Each of these code units will not have a conversion rate (it will appear as N/A
).
Se o código de entrada incluir apenas unidades de código fora do escopo, a taxa de conversão de linhas de código de toda a migração será de 0%.
A seguinte CREATE TRIGGER
é considerada uma unidade de código fora do escopo.
CREATE OR REPLACE TRIGGER my_trigger
AFTER
UPDATE
ON my_table
FOR EACH ROW
BEGIN
NULL;
END;
Exemplos de unidades de código de nível superior¶
Na seção a seguir, podemos ver alguns exemplos de unidades de código de nível superior.
Consultas¶
No exemplo a seguir, temos aqui uma única instrução SELECT. Essa instrução é uma única unidade de código de nível superior.
SELECT * FROM table1;
Neste exemplo, temos uma instrução SELECT
aninhada dentro de outra instrução SELECT
. A consulta inteira conta como uma única unidade de código de nível superior.
SELECT * FROM (SELECT * FROM table1);
Objetos¶
Os objetos criados com um DDL contam como uma única unidade de código de nível superior, mesmo que contenham outras unidades de código em seu interior.
A instrução a seguir cria uma exibição com uma consulta. Nesse caso, CREATE VIEW
inteiro conta como uma única unidade de código de nível superior.
CREATE VIEW view1 AS SELECT * FROM table1;
A seguinte instrução CREATE PROCEDURE
conta como uma única unidade de código de nível superior, mesmo que contenha vários comandos dentro dele.
CREATE PROCEDURE procedure1
AS
BEGIN
DELETE FROM table1;
END;
Comandos¶
Os comandos independentes em um arquivo SQL são considerados unidades de código de nível superior.
Uma instrução COMMIT
conta como uma única unidade de código de nível superior.
COMMIT;
Corpos de pacotes no Oracle¶
Um pacote pode definir vários elementos dentro de seu corpo. O corpo do pacote é considerado a unidade de código de nível superior porque esses elementos não podem ser criados individualmente sem a criação de todo o corpo do pacote. Os elementos ou unidades de código dentro do corpo de um pacote não contarão como unidades de código de nível superior.
O código a seguir será relatado como uma única unidade de código CREATE PACKAGE BODY
.
CREATE PACKAGE package_body1 IS
FUNCTION function1
RETURN VARCHAR
IS
BEGIN
RETURN 'HELLO'';
END;
END;
Arquivos de script do Teradata¶
Os arquivos de Script do Teradata, como BTEQ ou TPUMP, são executados como unidades de código autônomas. Por esse motivo, o arquivo inteiro é considerado uma única unidade de código de nível superior. Outras unidades de código possíveis dentro desses arquivos não contarão como unidades de código de nível superior.
O seguinte arquivo de script BTEQ será relatado como uma única unidade de código de nível superior BTEQ.
.LOGON e/fml,notebook
.COMPILE FILE = example.spl;
COMMIT;
CALL samplesp1 (8888, pAmount);
.LOGOFF
Transacionar lotes SQL com GOTO¶
Cada instrução do Transact-SQL pode ser executada de forma independente. Na maioria dos casos, cada uma dessas instruções é considerada uma unidade de código de nível superior. No entanto, quando há um lote que contém uma instrução GOTO para um rótulo dentro do mesmo lote, as instruções do lote não podem ser executadas independentemente sem garantir que funcionem corretamente. Por esse motivo, as instruções que estiverem em um lote com uma instrução GOTO não contarão como unidades de código de nível superior, apenas o lote.
O exemplo de código a seguir será relatado como uma única unidade de código GOTO/LABEL:
DECLARE @Counter int;
SET @Counter = 1;
WHILE @Counter < 10
BEGIN
SELECT @Counter
SET @Counter = @Counter + 1
IF @Counter = 4 GOTO Branch_One
IF @Counter = 5 GOTO Branch_Two
END
Branch_One:
SELECT 'Jumping To Branch One.'
GOTO Branch_Three;
Branch_Two:
SELECT 'Jumping To Branch Two.'
Branch_Three:
SELECT 'Jumping To Branch Three.';
GO
Como a metodologia da Unidade de Código é representada em outros relatórios?¶
A metodologia da Unidade de Código também está representada em outros relatórios. Esta seção explica como esses valores são mostrados ou estão relacionados a outros relatórios.
Relatório de problemas¶
Cada linha do Relatório de problemas contém algumas informações sobre a Unidade de código que está sendo afetada pelo problema. As colunas relacionadas às unidades de código são as seguintes:
Code Unit Database: Esse é o banco de dados da unidade de código de nível superior em que o problema foi encontrado. Isso se aplica apenas a unidades de código que são objetos.
Code Unit Schema: Esse é o esquema da unidade de código de nível superior em que o problema foi encontrado. Isso se aplica apenas a unidades de código que são objetos.
Code Unit Package: Este é o pacote da unidade de código de nível superior em que o problema foi encontrado. Isso se aplica apenas a unidades de código que são objetos.
Code Unit Name: Esse é o nome da unidade de código de nível superior em que o problema foi encontrado. Isso se aplica apenas a unidades de código nomeadas, como objetos. Esse nome não é qualificado por banco de dados, esquema ou pacote.
Code Unit ID: Este é o ID da unidade de código de nível superior onde o problema foi encontrado. Esse nome tem o nome qualificado e adicionará um número para unidades de código com nomes repetidos.
Code Unit: Esse é o tipo da unidade de código de nível superior em que o problema foi encontrado.
Code Unit Size: Esse é o tamanho da unidade de código de nível superior em que o problema foi encontrado.
Relatório de referências a objetos e relatório de objetos ausentes¶
Cada linha do relatório Object References contém informações sobre a unidade de código de nível superior que estava fazendo referência a outro elemento. Esses elementos referenciados podem não ser de nível superior, portanto, esses outros valores podem não ser incluídos no relatório Top-Level Code Units.
Da mesma forma que o relatório Object References, o relatório Missing Objects contém informações sobre a unidade de código de nível superior que fazia referência a um elemento que não podia ser encontrado no código.
Caller Code Unit: Esse é o tipo da unidade de código de nível superior que está fazendo referência a outro elemento.
Caller Code Unit Database: Esse é o banco de dados da unidade de código de nível superior que está fazendo referência a outro elemento.
Caller Code Unit Schema: Esse é o esquema da unidade de código de nível superior que está fazendo referência a outro elemento.
Caller Code Unit Name: Esse é o nome da unidade de código de nível superior que está fazendo referência a outro elemento.
Caller Code Unit Full Name: Este é o nome completo da unidade de código de nível superior que está fazendo referência a outro elemento.
Informações no relatório Top-Level Code Units¶
Coluna |
Descrição |
---|---|
Chave de partição |
O identificador exclusivo da conversão. |
Tipo de arquivo |
O tipo de arquivo em que a unidade de código está. (SQL, BTEQ, etc…) |
Categoria |
A classe ou o tipo mais amplo a que cada unidade de código pertence. |
Code Unit |
O tipo de unidade de código ao qual esse elemento pertence. |
Code Unit Name |
O nome da unidade de código, se houver uma, como tabelas ou procedimentos. Será N/A para elementos sem um nome como DMLs. |
Nome do arquivo |
O nome do arquivo no qual o objeto está localizado. Usa o caminho relativo a partir do diretório de entrada. |
Line Number |
O número da linha dentro do arquivo em que a unidade de código está localizada. |
Linhas de código |
O total de linhas de código que a unidade de código tem. |
EWI Count |
A quantidade de EWIs encontrada na unidade de código. Você pode saber mais sobre EWIs aqui. |
FDM Count |
A quantidade de FDMs encontrada na unidade de código. Você pode saber mais sobre FDMs aqui. |
PRF Count |
The amount of PRFs found within the code unit. You can learn more about PRFs here. |
Highest EWI Severity |
<p>O EWI com maior gravidade encontrado na unidade de código.<br>A ordem de gravidade é a seguinte:</p><ul><li>N/A (quando não há nenhum EWIs)</li><li>Low</li><li>Medium</li><li>High</li><li>Critical</li></ul> |
UDFs Used |
Os nomes de todas as funções definidas pelo usuário encontradas na unidade de código. O nome dos UDFs usado é separado por um pipe se houver mais de um. |
EWI |
Os códigos de todos os EWIs encontrados na unidade de código. Esses códigos são separados por pipes e não incluem códigos repetidos. |
FDM |
Os códigos de todos os FDMs encontrados na unidade de código. Esses códigos são separados por pipes e não incluem códigos repetidos. |
PRF |
Os códigos de todos os PRFs encontrados na unidade de código. Esses códigos são separados por pipes e não incluem códigos repetidos. |
Status da conversão |
<p>O status final da conversão da unidade de código.</p><p>Os possíveis status de conversão são:</p><ul><li>NotSupported: Quando a unidade de código tem uma taxa de conversão de 0%.</li><li>Partial: Quando a taxa de conversão da unidade de código está entre 0% e 100%.</li><li>Success: Quando a taxa de conversão da unidade de código é de 100%.</li></ul> |
LoC Conversion Percentage |
A porcentagem de conversão é baseada em linhas de código. Uma única linha de código pode ter fragmentos compatíveis e não compatíveis, dependendo de como o código de entrada foi formatado. Nesses casos, a linha inteira é considerada não compatível. |
Deployment Order |
The deployment order is the topological level of each code unit based on its dependencies. It shows the right order in which the code units should be deployed to avoid missing dependencies during the deployment phase. |
Exemplo¶
Suponha que o seguinte CREATE TABLE
em ORACLE SQL esteja localizado em seu arquivo chamado table_example.sql.
CREATE TABLE my_table (
my_column DATE DEFAULT TO_DATE(CURRENT_DATE, 'J'),
NOT A VALID COLUMN
);
CREATE OR REPLACE TABLE my_table (
my_column TIMESTAMP /*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/ DEFAULT PUBLIC.JULIAN_TO_GREGORIAN_DATE_UDF(CURRENT_DATE(), 'J')
-- ,
-- ** SSC-EWI-0001 - UNRECOGNIZED TOKEN ON LINE '3' COLUMN '3' OF THE SOURCE CODE STARTING AT 'NOT'. EXPECTED 'Column Definition' GRAMMAR. LAST MATCHING TOKEN WAS ',' ON LINE '2' COLUMN '52'. FAILED TOKEN WAS 'NOT' ON LINE '3' COLUMN '3'. CODE '15'. **
-- NOT A VALID COLUMN
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
;
O relatório Top-Level Code Units terá uma única entrada da tabela mostrada anteriormente.
Aqui estão todos os valores que seriam informados na entrada dessa instrução CREATE TABLE
:
O valor de Partition Key dependerá da migração, portanto, o valor aqui poderá variar.
O File Type será SQL porque foi migrado em um arquivo com a extensão .sql.
A Category será TABLE porque a instrução
CREATE TABLE
faz parte da categoria de unidade de código TABLE.A Code Unit em si será
CREATE TABLE
.O File Name onde essa unidade de código foi encontrada seria table_example.sql.
Supondo que a instrução
CREATE TABLE
esteja no início do arquivo, o número da linha será 1.O número de linhas de código seria 4.
A coluna EWI Count informará 1 porque o código de saída tem um EWI de análise.
A coluna FDM Count informará 1 porque o código de saída tem um problema FDM relacionado a tipos de dados.
O PRF Count informará 0 porque não há problemas de PRF presentes no código de saída.
O Highest EWI Severity nesse caso seria «Critical» porque essa é a gravidade da análise de EWI do exemplo. O outro tem uma gravidade «Low».
A coluna UDFs Used será
JULIAN_TO_GREGORIAN_DATE_UDF
porque essa Função Definida pelo Usuário personalizada foi adicionada para converter a funçãoTO_DATE
do código de entrada.A coluna EWI informará «SSC-EWI-0001» porque esse foi um dos EWIs adicionados no código de saída.
A coluna FDM informará «SSC-FDM-OR0042» porque esse foi um dos FDMs adicionados no código de saída.
A coluna PRF informará «N/A» porque não há problemas de PRF presentes no código de saída.
O Conversion Status será «Partial» porque apenas alguns fragmentos dessa unidade de código puderam ser migrados sem EWIs.
A LoC Conversion Percentage é de 50% porque, de 4 linhas, apenas 2 foram convertidas com sucesso.
Deployment Order¶
The deployment order column represents the correct order to deploy each code unit into Snowflake.
The following code exemplifies in depth how the deployment order is calculated.
CREATE TABLE TABLE1 ( -- level 0, no dependencies
COL1 INT
);
CREATE TABLE TABLE2 ( -- level 0, no dependencies
COL1 INT
);
CREATE VIEW VIEW1 -- level 4, depends on level-3 objects
AS SELECT * FROM VIEW2, VIEW3;
CREATE VIEW VIEW2 -- level 3, depends on level-2 objects
AS SELECT * FROM VIEW4, VIEW5, VIEW3;
CREATE VIEW VIEW4 -- level 1, depends on level-0 objects
AS SELECT * FROM TABLE1, TABLE2;
CREATE VIEW VIEW5 -- level 1, depends on level-0 objects
AS SELECT * FROM TABLE1;
CREATE VIEW VIEW3 -- level 2, depends on level-1 objects
AS SELECT * FROM VIEW6;
CREATE VIEW VIEW6 -- level 1, depends on level-0 objects
AS SELECT * FROM TABLE2;
The deployment order starts with 0
, so code units without any dependencies will start at this level. In the example above, TABLE1
and TABLE2
will have a level 0
.
For the next level, we will focus on code units that depend on code units of level 0
. VIEW4
, VIEW5
, and VIEW6
depend directly on TABLE1
and TABLE2
, so their level will be 1
.
After identifying all the code units of level 1
, we will focus on code units of level 2
. In that particular scenario, just VIEW3
depends on VIEW6
, so VIEW3
will be level 2
.
Once we identify all code units of level 2
, we will focus on level 3. In the example above, VIEW2
depends on VIEW4
, VIEW5
and VIEW3
, however, the highest dependency level is 2
, so, VIEW2
will be of level 3
.
Finally, we got VIEW1
, which depends on VIEW2
and VIEW3
. Since VIEW2
is the dependency with higher level, VIEW1
will get level 4
.
After making all the calculations, the top-level code units report will look something like the following table.
Code Unit Id |
Deployment Order |
---|---|
VIEW1 |
4 |
VIEW2 |
3 |
VIEW3 |
2 |
VIEW4 |
1 |
VIEW5 |
1 |
VIEW6 |
1 |
TABLE1 |
0 |
TABLE2 |
0 |
Limitations¶
There are some scenarios where the deployment order may not calculate the right level for a specific code unit.
Code Units with Missing Dependencies¶
Deployment of code units that depend (directly or indirectly) on missing objects is not possible. Although SnowConvert AI calculates the deployment order as best it can, a missing dependency will cause deployment errors. For code units with missing dependencies, SnowConvert AI adds an asterisk (*) alongside the deployment order. E.g.
CREATE TABLE TABLE1 ( -- level 0, no dependencies
COL1 INT
);
CREATE VIEW VIEW1 -- level 1*, depends on level-0 objects and has a missing dependency
AS SELECT * FROM TABLE1, TABLE2;
CREATE VIEW VIEW2 -- level 2*, depends on level-1* objects
AS SELECT * FROM VIEW1;
The example above shows VIEW1
referencing a missing TABLE2
and VIEW2
referencing ,VIEW1
which indirectly refers TABLE2
. VIEW1
has a direct missing reference and VIEW2
an indirect missing reference. The top-level code units report will look something like the following table.
Code Unit Id |
Deployment Order |
---|---|
TABLE1 |
0 |
VIEW1 |
1* |
VIEW2 |
2* |
Code Units referencing Database Links (Oracle)¶
While SnowConvert AI can identify references to Database Links, it cannot get more information about the objects being referenced through the database link. This kind of reference may cause trouble during deployment as well, so it will be handled the same way as missing object references. E.g.
CREATE DATABASE LINK DBLINK1
CONNECT TO PUBLIC IDENTIFIED BY VALUES ':1'
USING 'TEST';
CREATE MATERIALIZED VIEW VIEW1 REFRESH WITH ROWID
AS SELECT * FROM TABLE1@DBLINK1;
VIEW1
is referencing TABLE1
through the database link DBLINK1
. Since we don’t know where TABLE1
is located, the deployment order of VIEW1
will be handled like a deployment order with missing dependencies (*).
Code Unit Id |
Deployment Order |
---|---|
DBLINK1 |
0 |
VIEW1 |
1* |
Code Units referencing DDLs defined inside Stored Procedures, Anonymous Blocks, etc¶
In some scenarios, the deployment order may not be correct because the referenced element was defined inside another code unit. E.g.
CREATE TABLE TABLE1 (
COL1 INT
);
CREATE OR REPLACE PROCEDURE PROC1 (param1 NUMBER)
IS
BEGIN
CREATE VIEW VIEW1
AS
SELECT * FROM TABLE1;
END;
CREATE VIEW VIEW2
AS SELECT * FROM VIEW1;
In the code above, VIEW2
references VIEW1
, which will be created after executing the stored procedure. VIEW1
references TABLE1
, so the procedure should be executed after creating the table. In that particular scenario, VIEW1
will not be included in the top-level code units report since it is contained by the stored procedure. In that case, for VIEW2
is not possible to know that VIEW1
depends on PROC1 to be created, and the deployment order may not be correct because of that. The following table shows the deployment order for the code above.
Code Unit Id |
Deployment Order |
---|---|
TABLE1 |
0 |
PROC1 |
1 |
VIEW2 |
1 |
Despite VIEW1
and PROC1
having the same deployment order, VIEW1
will fail if the procedure was not executed first.
Aviso
Deployment Order support for Sequences is going to be delivered in a future version. By default, Code Units referencing sequences are not considering them to calculate the deployment order.