PostgreSQL, Pl/pgsql - How to access a query string that executed the stored procedure i'm in? - postgresql

is there a way to access the query string from within a stored procedure?
i mean i'd like to add some debugging to a lot of stored procedures and it would be brilliant if i had some constant accessible from the body of the procedure, which had the query string.
something which would work with EXECUTE.
i've read the docs and cannot see anything like that...
thanks!

I agree with Pavel that your requirement is not real clear. However, I guess that you want the to get the statement that called the procedure currently running. If so then there may be a built in function: Current_Query(). Following is an example of its use.
create or replace function what_called_me()
returns text
language sql
as $$
select current_query();
$$;
select 1 num, 'A' col, what_called_me() sql_statement;

I don't understand well, what you need, but maybe you need plpgsql plugin API. This API is not well documented, but there is lot of PostgreSQL extensions that use this API - PLdebugger, plpgsql_chec, plprofiler and maybe other.
/*
* A PLpgSQL_plugin structure represents an instrumentation plugin.
* To instrument PL/pgSQL, a plugin library must access the rendezvous
* variable "PLpgSQL_plugin" and set it to point to a PLpgSQL_plugin struct.
* Typically the struct could just be static data in the plugin library.
* We expect that a plugin would do this at library load time (_PG_init()).
* It must also be careful to set the rendezvous variable back to NULL
* if it is unloaded (_PG_fini()).
*
* This structure is basically a collection of function pointers --- at
* various interesting points in pl_exec.c, we call these functions
* (if the pointers are non-NULL) to give the plugin a chance to watch
* what we are doing.
*
* func_setup is called when we start a function, before we've initialized
* the local variables defined by the function.
*
* func_beg is called when we start a function, after we've initialized
* the local variables.
*
* func_end is called at the end of a function.
*
* stmt_beg and stmt_end are called before and after (respectively) each
* statement.
*
* Also, immediately before any call to func_setup, PL/pgSQL fills in the
* error_callback and assign_expr fields with pointers to its own
* plpgsql_exec_error_callback and exec_assign_expr functions. This is
* a somewhat ad-hoc expedient to simplify life for debugger plugins.
*/
typedef struct PLpgSQL_plugin
{
/* Function pointers set up by the plugin */
void (*func_setup) (PLpgSQL_execstate *estate, PLpgSQL_function *func);
void (*func_beg) (PLpgSQL_execstate *estate, PLpgSQL_function *func);
void (*func_end) (PLpgSQL_execstate *estate, PLpgSQL_function *func);
void (*stmt_beg) (PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt);
void (*stmt_end) (PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt);
/* Function pointers set by PL/pgSQL itself */
void (*error_callback) (void *arg);
void (*assign_expr) (PLpgSQL_execstate *estate, PLpgSQL_datum *target,
PLpgSQL_expr *expr);
} PLpgSQL_plugin;
This is necessary when you really need to detail info about what is inside.
Maybe you need information just about executed queries - then you can look on extension auto_explain, when you set auto_explain.log_nested_statements to on, then the queries from procedure will be logged.

Related

Doxygen repeating text

In all my APIs I have a line of text that gets repeated. Is there a way to put that text in one place and link to it from the APIs?
For instance, in the below example, how to put the 'text that is common for many APIs' in one place, instead of writing the same thing in all the APIs?
/**
* #brief Function description
* #param [in] param function param description
* #return return description
*
* #attention text that is common for many APIs
***********************************************************************/
int func(int param);
In case it is always the same line, best would be to define a special command for it by means of and alias in the doxygen configuration file (Doxyfile), see the tag ALIASES
For longer texts the doxygen command \includedoc would be the way to go.

How do I use a PostgreSQL function that returns a table as a CakePHP 3 Model?

Using Cake PHP 3.x and we have a PostgreSQL 9.6.3 db.
We make extensive use of PG functions that return tables - for example
select * from getStudies(cid,UID, SID);
Functions are used for various applications - one of them is more complex filtering of rows from a table - where Cake has difficulty.
One option is to implement the logic as a custom Cake Model method in PHP, but the SQL code and amount of joins makes it messy in PHP.
We think we should be able to create a Cake Model from the function and then pass the parameters via Cake Model methods but so far - it is unclear how to do that.
This code works but it returns the data without the columns and I have not been able to figure out how to use reflection to get the _columns properties from the Model schema.
public function getStudies($data = array()) {
$customer_id = $data['customer_id'];
$connection = ConnectionManager::get('default');
$sql = "select * from getStudies($customer_id)";
$results = $stmt->fetch();
return $results; }
So -
Option 1 - figure out how to model a function that returns tables as a cake model
Option 2 - use reflection to get the _columns and merge it with the query result
Thanks
As you've mentioned in the comments, the schema columns details can be accessed via its columns() method. You could process the results manually using the schema information, or use the function as the source, just like in your example.
The query builders from() method supports raw SQL as well as expressions, so you can basically add whatever you like, however expressions will be wrapped in parentheses, which will be invalid SQL in case of a function call, so you'd have to go with raw SQL, and bindings (please never inject (user)data into queries directly):
public function getStudies($customerId)
{
return $this
->find()
->from([
$this->alias() => 'getStudies(:customerId)'
])
->bind(':customerId', $customerId, 'integer');
}
That should generate a query similar to
SELECT
Alias.column1, Alias.column2, ...
FROM
getStudies(:customerId) Alias

I can create a stored procure with invalid user defined function names in it

I just noticed that I could alter my stored procedure code with a misspelled user defined function in it.
I noticed that at 1st time I execute the SP.
Is there any way to get a compile error when an SP include an invalid user-defined function name in it?
At compile time? No.
You can, however, use some of SQL's dependency objects (if using MS SQL) to find problems just after deployment, or as part of your beta testing. Aaron Bertran has a pretty nice article rounding up the options, depending upon the version of SQL Server.
Here is an example using SQL Server 2008 sys object called sql_expression_dependencies
CREATE FUNCTION dbo.scalarTest
(
#input1 INT,
#input2 INT
)
RETURNS INT
AS
BEGIN
-- Declare the return variable here
DECLARE #ResultVar int
-- Add the T-SQL statements to compute the return value here
SELECT #ResultVar = #input1 * #input2
-- Return the result of the function
RETURN #ResultVar
END
GO
--Fn Works!
SELECT dbo.ScalarTest(2,2)
GO
CREATE PROCEDURE dbo.procTest
AS
BEGIN
SELECT TOP 1 dbo.scalarTest(3, 3) as procResult
FROM sys.objects
END
GO
--Sproc Works!
EXEC dbo.procTest
GO
--Remove a dependency needed by our sproc
DROP FUNCTION dbo.scalarTest
GO
--Does anything have a broken dependency? YES
SELECT OBJECT_NAME(referencing_id) AS referencing_entity_name,
referenced_entity_name, *
FROM sys.sql_expression_dependencies
WHERE referenced_id IS NULL --dependency is missing
GO
--Does it work? No
EXEC dbo.procTest
GO

Doxygen - how to document a variable so I can see its type

I'm sorry if it sounds too simple a question but still ...
I am documenting php code and whereas all functions etc. look good in the generated documentation,
I have problems with variable types which should be visible in the generated documentation.
I document them in this way:
/**
* $request - request object
*
* #type int
* #access private
*/
private $request;
As a result, I can see 'int' in the generated documentation, but #type is not a correct command. The proper command would be #var instead of #type but then I cannot see the type of the variable in the documentation.
So the question is "How to document a variable so I can see its type?"
Please help :)

AspectJ Used to profile query execution making aplicaiont too slow

I am using AspecJ to capture the query being executed in each of the form and show the time each query takes to execute. We are using spring jdbc and my aspect look as below:
#Aspect
public class QueryProfilerAspect {
#Pointcut("call(* org.springframework.jdbc.core.simple.SimpleJdbcTemplate.query* (..))")
public void profileQuery() {
}
#Around("profileQuery()")
public Object profile(ProceedingJoinPoint thisJoinPoint) throws Throwable {
// System.out.println("Inside join point execution");
SimpleJdbcTemplate template = (SimpleJdbcTemplate) thisJoinPoint
.getTarget();
JdbcTemplate jdbcTemplate = (JdbcTemplate) template
.getNamedParameterJdbcOperations().getJdbcOperations();
DataSource ds = jdbcTemplate.getDataSource();
// System.out.println("Datasource name URL =="
// + ds.getConnection().getMetaData().getURL());
// System.out.println("Datasource name ==" + schemaName);
String sqlQuery = thisJoinPoint.getArgs()[0].toString();
final long start, end;
start = System.nanoTime();
Object ll = thisJoinPoint.proceed();
end = System.nanoTime();
long executionTime = ((end - start) / 1000) / 1000;
System.out.println("execution_time=" +executionTime + sqlquery="+sqlQuery );
return ll;
}
Functionality wise this works however if i put this i my application it makes the application too slow. I am using compile time weaving. And the aspect finds 1683 query* method calls within the application.
Is there anything I can do to optimize this. Any suggestion/help will be really appreciated.
First I would advice against using System.nanoTime(). It's precision using cold like that is atrocious and pretty much useless for measuring timespans. Certainly not better than System.currentTimeMillies() if you divide the result anyway.
What probably slows you down most though, are the the String operations performed at various places in your aspect. If you have to concatenate Strings, at least use a StringBuilder to do so before outputting it. That might be done by the optimizer already, but you can never be too sure. ;)
And... Sysout isn't exactly the way to go if you want logging - looking into one of the various logging implementations (slf4j with logback is my personal favourite, but there are others as well) will be worth your time.
Especially if you want to use the fact that Spring has the feature you are trying to build (, as asked and answered here before: Seeing the underlying SQL in the Spring JdbcTemplate?
(Edit: I know it's only the query, not the time measuring, but not having to worry about that should shave some time off your overhead as well.)