SOCI, pgsql function returning table record - type_conversion not working - c++

I have a pgsql function declared as:
CREATE FUNCTION auth.read_session(session_id varchar) RETURNS auth.sessions
It returns one record from the table auth.sessions.
I have a SOCI type_conversion that works perfectly fine when
I run select * from auth.sessions where id = :id.
It works when a matching record is found and when the result is NULL.
However, when I change the statement to:
select * from auth.read_session('invalid');
I get exception:
Null value not allowed for this type while executing "select * from
auth.read_session('invalid')".
I tried with listing columns, passing soci::indicator, etc.
I cannot get it to work.
The exception comes from base type_conversion<>.
In type-conversion-traits.h there is a comment stating that:
// default traits class type_conversion, acts as pass through for
row::get() // when no actual conversion is needed.
Why is no conversion needed? Yes my function returns the record of table type "auth.sessions".
Should it return RECORD instead so that the conversion gets launched?

Apparently the only way this can be done is having the function return SETOF records. I believe the conversion is not needed as in my case the whole result was NULL and it cannot be somehow cast to my own type.
Returning a single record of table type works as long as there is any result.
It would work if a function was designed to always return a record, even if an empty one, but still a "record".

PadThink you're right about the return. To call this function the way you're doing you need to return a QUERY, TABLE, or SETOF records.
http://www.postgresql.org/docs/9.2/static/xfunc-sql.html

Related

Querying a mixed type column in Amazon Athena

I have an Athena table that has a column in it that I would like to query. The type of the column is double, but it contains data of mixed types. The data is either:
A double (0-1 inclusive)
An array with 0 or 1 elements (again, a double 0-1 inclusive).
I have no idea how the column go into this state. I'm just trying to fix it.
If I do a naive query:
SELECT col FROM tbl.db;
I get the error: "HIVE_BAD_DATA: Error parsing field value '[]' for field 0: org.openx.data.jsonserde.json.JSONArray cannot be cast to java.lang.Double"
Some things that I've tried, but don't work:
Use try_cast
The docs on try_cast make it sound like the perfect solution; reality is not so kind.
When I tried to run
SELECT COALESCE(
try_cast(col AS double),
try_cast(col AS array<double>)) FROM tbl.db;
I get the error: "SYNTAX_ERROR: line 3:5: Cannot cast double to array(double)". Indeed, when I try more simple examples, I continue to get an error: both
SELECT try_cast(3.4 AS array<double>);
SELECT try_cast(ARRAY [3.4] AS double);
trigger errors. It appears that, although the docs claim that a cast error would cause the function to return null, perhaps that only works when casting between primitive data types.
Cast to JSON
While casting both doubles and arrays to JSON works fine as in these examples:
SELECT try_cast(3.4 AS JSON);
SELECT try_cast(ARRAY [3.4] AS JSON);
when I perform the cast on the actual column like so:
SELECT try_cast(col AS JSON) FROM tbl.db;
I get the error: "HIVE_BAD_DATA: Error parsing field value '["0.01"]' for field 0: org.openx.data.jsonserde.json.JSONArray cannot be cast to java.lang.Double"
I'd really like to be able to query this data. Alternatively, if it's possible to migrate it into a state where it's all one type, that would be an acceptable solution as well.

Custom Function Using Column As Parameter

I have a custom function created in the Power Query Editor that accepts two parameters. One parameter should be dynamic based upon the value in a column. When tested with static parameters, the function works correctly as far as using a static parameters goes. However, if the table column is supplied (to provide the dynamic value needed), it produces a cyclical error. The function is invoked using "Invoke Custom Function". The first parameter selects a field, while the second parameter is set statically.
The Invoke Custom Function that produces a correct result:
= Table.AddColumn(#"Rounded Up", "qryProjectedDate", each qryProjectedDate(5, -1))
The Invoke Custom Function that produces an error:
= Table.AddColumn(#"Rounded Up", "qryProjectedDate", each qryProjectedDate([RemainingBudgetDays_RndUp], -1))
The qryProjectedDate:
(TotalLoops as number, Loop as number) =>
let
CurrentLoop = Loop + 1,
output =
if Calendar[IsWorkDay]{CurrentLoop} = 1
then
(if CurrentLoop = TotalLoops - 1
then Calendar[Date]{CurrentLoop}
else #qryProjectedDate(TotalLoops, CurrentLoop))
else #qryProjectedDate(TotalLoops + 1, CurrentLoop)
in output as date
This function produces a stack overflow error and a cyclical error messages.
Further testing of just inputting the column value as a parameter and returning that same value produces the value that I would expect. Therefore, I believe my issue is in how I have written the power query M function.
if function(5,-1) works then using function([column1],-1) will also work if column1 contains a numeric five
Are you sure the column is named RemainingBudgetDays_RndUp ? Spelling and capitalization of the column name matter. Try temporarily renaming that column and look at the output to see what powerquery thinks that column is named
Once that is set, is the column formatted as numeric or alpha? If not numeric, change the column type or use Number.From() in your function
Try calling your function using a table with a single row, and the contents of the RemainingBudgetDays_RndUp column equal to a numeric five. Does it work? Then the data needs cleaning on some of the rows
Are there any nulls, alpha characters, out of bound, or other data in the RemainingBudgetDays_RndUp column that will break your function? To guard against that, try adding a try and otherwise null before and after strategic points in the function

How to use a query as a parameter for a function?

I just refactored into a power query function some code that process tables that has an specific structure.
Now, I need to pass another PowerQuery query (that returns a table with a compatible structure) to this function, but the parameter manager only allows to use strings, therefore I need to obtain access to the referenced table using an string with its name.
Any hints?

vc++ (sqlite)how to distingush statement is SELECT - or NOT?

My code is necessary to distinguish whether Sql statement is SELECT or not.
If the result is more than 1, it is easy to distinguish select.
But there is no result when the statement executed, how do I distinguish it?
sqlite_stmt *some_stmt;
//case 1 : (the table has no row)
sqlite3_prepare("select * from some_table", &some_stmt);
//case 2 :
sqlite3_prepare("create table some_table2", &some_stmt);
int result = sqlite3_step(some_stmt);
result is same :
SQLITE_DONE;
I can distinguish it with two method,
1st is get substring from the statement. but i don't want do it, it seems to be incorrectly way.
2st is use sqlite3_column_count(). Usually column_count has one or more than if the statement is SELECT.
Is it correct way using sqlite3_coulmn_count()? Isn't there anything that No-column-table in sqlite or etc?
I want correct way to distinguish whether Statement is SELECT or Not.
There are other statements that return data (e.g., some PRAGMAs), so you cannot search for "SELECT".
As documented, sqlite3_column_count() is the correct way:
This routine returns 0 if pStmt is an SQL statement that does not return data (for example an UPDATE).
In SQL, there is no such thing as a table without columns. Even in a construct that does not actually look at any data (such as EXISTS (SELECT ...)), you have to use some dummy column(s).

SQLite bind parameter to wildcard

I've created a query to delete rows from my table if they match some criteria.
sqlite3_prepare(sqlite->db, "DELETE FROM test WHERE field1=? AND field2=? AND field3=? AND field4=? AND field5=?", -1, &sqlite->deleteSymbol, 0);
I then bind them to NULL terminated strings. However, if any of the strings passed by the caller of my function is NULL, then this means that any value for the given column should match.
I.e., if field1, field3 and field5 are NULL, then the query would be equivalent to
DELETE FROM test WHERE field2=? AND field4=?
Can this be achieved while reusing the output of sqlite3_prepare, without creating separate queries for each combination of NULL/non-NULL strings?
A parameter always replaces one specific value, or NULL.
What you want to do is to change the semantics of the = operator, but this is not possible by changing one of its operand values.
Just prepare a new DELETE command.
There is no big overhead in preparing a simple statement like this.