Null / Out of Bounds Error when running Liquibase - grails

I am using the database-migration Grails plugin. But running dbm-update runs into fatal errors for some of my sql when using the liquibase formatted sql migrations. I get this error:
liquibase : 'Change Set GraphFunctions.sql::graph_functions_initialize_1::<user> failed. Error: null'
java.lang.ArrayIndexOutOfBoundsException
This happens when I run the code:
--changeset <username>:graph_functions_initialize_1
CREATE OR REPLACE FUNCTION build_trcd(
IN new_parent_id bigint,
IN new_child_id bigint)
RETURNS TABLE(ancestor_id bigint, descendant_id bigint, paths bigint, cost bigint) AS '
SELECT
t1.ancestor_id AS ancestor_id,
t2.descendant_id AS descendant_id,
SUM(t1.paths*t2.paths)::bigint AS paths,
MIN(t1."cost"+t2."cost")+1::bigint AS "cost"
FROM db_set_membership_closure t1, db_set_membership_closure t2
WHERE t1.descendant_id=new_parent_id AND t2.ancestor_id=NEW_child_id
GROUP BY t1.ancestor_id, t2.descendant_id
UNION
SELECT
NEW_parent_id AS ancestor_id,
descendant_id AS descendant_id,
paths AS paths ,
(c."cost" + 1)::bigint AS "cost"
FROM db_set_membership_closure c
WHERE ancestor_id = NEW_child_id
UNION
SELECT
ancestor_id AS ancestor_id,
NEW_child_id AS descendant_id,
paths AS paths,
c."cost" + 1::bigint AS "cost"
FROM db_set_membership_closure c
WHERE descendant_id = NEW_parent_id
UNION VALUES (NEW_parent_id, NEW_child_id,1::bigint,1::bigint);
' LANGUAGE sql;
--rollback drop function build_trcd;
If I don't use formatted-sql then it runs fine. However, if I do that, then I cannot manage a rollback through the Liquibase interface. Does anyone have an insight into what I might change to make this work?

It turns out that sql changesets including function declarations have been failing because they contain semi-colons in the middle of the create statement. To fix these errors I just had to change the formatted-sql to not split the statements:
--changeset <username>:graph_functions_initialize_1 splitStatements:false

Related

bigquery sql table function with string interpolation

I am trying to write a BigQuery SQL function / stored procedure / table function that accepts as input:
a INT64 filter for the WHERE clause,
a table name (STRING type) as fully qualified name e.g. project_id.dataset_name.table_name
The idea is to dynamically figure out the table name and provide a filter to slice the data to return as a table.
However if try to write a Table Function (TVF) and I use SET to start dynamically writing the SQL to execute, then I see this error:
Syntax error: Expected "(" or keyword SELECT or keyword WITH but got keyword SET at [4:5]
If I try to write a stored procedure, then it expects BEGIN and END and throws this error:
Syntax error: Expected keyword BEGIN or keyword LANGUAGE but got keyword AS at [3:1]
If I try to add those, then I get various validation errors basically because I need to remove the WITH using CTEs (Common Table Expression), and semicolons ; etc.
But what I am really trying to do is using a table function:
to combine some CTEs dynamically with those inputs above (e.g. the input table name),
to PIVOT that data,
to then eventually return a table as a result of a SELECT.
A bit like producing a View that could be used in other SQL queries, but without creating the view (because the slice of data can be decided dynamically with the other INT64 input filter).
Once I dynamically build the SQL string I would like to EXECUTE IMMEDIATE that SQL and provide a SELECT as a final step of the table function to return the "dynamic table".
The thing is that:
I don't know before runtime the name of this table.
But I have all these tables with the same structure, so the SQL should apply to all of them.
Is this possible at all?
This is the not-so-working SQL I am trying to work around. See what I am trying to inject with %s and num_days:
CREATE OR REPLACE TABLE FUNCTION `my_dataset.my_table_func_name`(num_days INT64, fqn_org_table STRING)
AS (
-- this SET breaks !!!
SET f_query = """
WITH report_cst_t AS (
SELECT
DATE(start) as day,
entity_id,
conn_sub_type,
FROM `%s` AS oa
CROSS JOIN UNNEST(oa.connection_sub_type) AS conn_sub_type
WHERE
DATE(start) > DATE_SUB(CURRENT_DATE(), INTERVAL num_days DAY)
AND oa.entity_id IN ('my-very-long-id')
ORDER BY 1, 2 ASC
),
cst AS (
SELECT * FROM
(SELECT day, entity_id, report_cst_t FROM report_cst_t)
PIVOT (COUNT(*) AS connection_sub_type FOR report_cst_t.conn_sub_type IN ('cat1', 'cat2','cat3' ))
)
""";
-- here I would like to EXECUTE IMMEDIATE !!!
SELECT
cst.day,
cst.entity_id,
cst.connection_sub_type_cat1 AS cst_cat1,
cst.connection_sub_type_cat2 AS cst_cat2,
cst.connection_sub_type_cat3 AS cst_cat3,
FROM cst
ORDER BY 1, 2 ASC
);
This might not be satisfying but since Procedural language or DDL are not allowed inside Table functions currently, one possible way around would be simply using PROCEDURE like below.
CREATE OR REPLACE PROCEDURE my_dataset.temp_procedure(filter_value INT64, table_name STRING)
BEGIN
EXECUTE IMMEDIATE FORMAT(CONCAT(
"SELECT year, COUNT(1) as record_count, ",
"FROM %s ",
"WHERE year = %d ",
"GROUP BY year ",
"; "
), table_name, filter_value);
END;
CALL my_dataset.temp_procedure(2002, 'bigquery-public-data.usa_names.usa_1910_current');

Informix grammar explanation?What does the grammar in the picture mean?

A fragment of SQL in the Informix dialect
SELECT INSUREDNAME
FROM sc5100car3gdb#idp_5100_cb:PRPCINSURED P
WHERE P.PROPOSALNO = A.PROPOSALNO
What does this grammar mean?
The SQL fragment is:
SELECT INSUREDNAME
FROM sc5100car3gdb#idp_5100_cb:PRPCINSURED P
WHERE P.PROPOSALNO = A.PROPOSALNO
This means that there is a table PRPCINSURED in database sc5100car3gdb hosted on Informix server idp_5100_cb; inside the query, the table will be referred to by the alias P. It has columns INSUREDNAME and PROPOSALNO. Further, this must be a fragment of an SQL statement. The WHERE clause uses the alias P, but also references another table with the alias (or perhaps name) A. However, the context defining A is not shown; as it stands, the A will trigger an error. (When I ran an analogous query, I got the error SQL -217: Column (a) not found in any table in the query (or SLV is undefined).)
See the Informix Guide to SQL: Syntax manual on database object names for more information about the notation used for the table name.

Redshift Stored Procedure - [Amazon](500310) Invalid operation: syntax error at or near "$1";

My Agenda is to store the counts of the 2 tables ( being passed in the parameter ) and then do some more operations upon comparing the both.
PROBLEM -
Stored Procedure throwing Error :
CREATE OR REPLACE PROCEDURE dev.gp_count_matching_20191204(actual_tablename character varying(256), bkp_tablename character varying(256))
LANGUAGE plpgsql
AS $$
DECLARE
actual_table_name varchar(256);
backup_table_name varchar(256);
actual_count_query varchar(1024);
actual_count int;
backup_count_query varchar(1024);
backup_count int;
BEGIN
call dev.gp_test_error_handling_tablename_format(actual_tablename);
call dev.gp_test_error_handling_tablename_format(bkp_tablename);
actual_count:=(select count(*) as counts from actual_tablename);
--raise info 'Actual Table Name - %, Actual Table Count - %',actual_tablename,actual_count;
end;
$$
This throws the following Error while creating the stored procedure-
An error occurred when executing the SQL command:
CREATE OR REPLACE PROCEDURE dev.gp_count_matching_20191204(actual_tablename character varying(256), bkp_tablename character varying(256))
LANGUAGE pl...
[Amazon](500310) Invalid operation: syntax error at or near "$1";
1 statement failed.
Execution time: 0.99s
If I comment out the actual_count:=(select count(*) as counts from actual_tablename);
then the Stored Procedure gets created Successfully.
I guess it has something to do with me using the parameter ( since $1 points the first parameter ) in the query.
Since I am pretty new with Stored procedure, I unable to figure out the exact problem.
Thanks in Advance.
You need to use EXECUTE when running dynamic SQL. In your example the query is in parentheses but nothing is making it execute. To execute the query into a variable you using the INTO syntax
sql := 'SELECT …'
EXECUTE sql_var INTO result_var;
Please see the example Stored Procedures in our GitHub repo "Amazon Redshift Utils". https://github.com/awslabs/amazon-redshift-utils/tree/master/src/StoredProcedures
There are several examples that use dynamic SQL, such as https://github.com/awslabs/amazon-redshift-utils/blob/master/src/StoredProcedures/sp_split_table_by_range.sql
You can also use the below-given syntax:
SELECT INTO Count count(*) from table_name;
By doing this you are inserting the value of count(*) into variable Count. It works.

Informix select into external syntax error

Can somebody please tell me what is the problem with the following informix statement :
SELECT * FROM
(some big query here)
INTO EXTERNAL empdata(selected_date date, land char, grund integer, some_user varchar, nr decimal(15))
USING (DATAFILES("DISK:/usr1/tbodan.out"))
I get a syntax error near INTO EXTERNAL empdata.
UPDATE
Informix version is 11.7 and omitting the column definition only brings the following error Error: Virtual column must have explicit name.
You need to follow the documented syntax at INTO EXTERNAL clause.
I think your problem is that you tried to provide column names and data types for the table.
This SQL worked for me:
SELECT * FROM elements
INTO EXTERNAL ext_elements
USING (DATAFILES("DISK:/Users/jleffler/tmp/ext-elements.table"))
This SQL did not, generating a -201 "A syntax error has occurred" error:
SELECT * FROM elements
INTO EXTERNAL ext_elements(atomic_number INTEGER, symbol CHAR(3),
name CHAR(20), atomic_weight DECIMAL(8,4),
pt_period SMALLINT, pt_group CHAR(2), stable CHAR(1))
USING (DATAFILES("DISK:/Users/jleffler/tmp/ext-elements.table"))
Testing on a Mac running macOS Sierra 10.12.5, using Informix 12.10.FC4.
Ok,so the problem was actually in the select query.
The query returns more columns that do not have an explicit name and are tagged as "expression" that is why the Error: Virtual column must have explicit name. popped up.
I solved this by using aliases for those columns. Then used the syntax suggested here.

db2 stored procedure to create a select query dynamically

I am new to IBM db2 stored procedure, what I am trying to do is to get the values of a column from a table and build a select query based on these values, this is what I have tried, not sure how to proceed
CREATE TYPE currencySymbols AS VARCHAR(20) ARRAY[100]#
CREATE PROCEDURE ins_curr_ano(IN crsymbol VARCHAR(20), IN cost1 integer, IN cost2 integer, IN teirId integer)
BEGIN
DECLARE currencies currencySymbols;
DECLARE maxCount INTEGER DEAFULT 0;
set currencies = ARRAY[SELECT distinct(CURR_SYMBOL) as currencySymbols FROM CURRENCY_MAPPING];
set maxCount = CARDINALITY(currencies);
for i in 1..maxCount loop
dbms_output.put_line(i);
end loop;
END#
Below is the error I am getting:
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0104N An unexpected token "loop" was found following "for i in
1..maxCount". Expected tokens may include: "(". LINE NUMBER=13.
SQLSTATE=42601
That for ... loop statement in your code has PL/SQL syntax, while everything else has DB2 SQL PL syntax. You cannot mix the two in the same routine.

Resources