postgres array range notation with jooq - postgresql

in my postgres database i have an array of jsons (json[]) to keep track of errors in the form of json objects. if an update comes in i want to append the latest error to that array but only keep the latest 5 errors (all sql is simplified):
update dc
set
error_history =
array_append(dc.error_history[array_length(dc.error_history, 1) - 4:array_length(dc.error_history, 1)+1], cast('{"blah": 6}' as json))
where dc.id = 'f57520db-5b03-4586-8e77-284ed2dca6b1'
;
this works fine in native sql, i tried to replicate this in jooq as follows:
.set(dc.ERROR_HISTORY,
field("array_append(dc.error_history[array_length(dc.error_history, 1) - 4:array_length(dc.error_history, 1) + 1], cast('{0}' as json))", dc.ERROR_HISTORY.getType(), latestError)
);
but it seems the : causes the library to think that there is a bind parameter there. the generated sql is:
array_append(dc.error_history[array_length(dc.error_history, 1) - 4?(dc.error_history, 1) + 1], cast('{0}' as json)
and the error i get is
nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "$5"
which i totally agree with :D
is there some way to escape the : in the java code or is there a better way to do this?
edit:
i have also tried just to remove the first element upon updating using the arrayRemove function but that also didn't work because it doesn't work by index but by element and postgres doesn't know how to check json elements for equality.

omg, the answer was really simple :D
field("array_append(dc.error_history[array_length(dc.error_history, 1) - 4 : array_length(dc.error_history, 1) + 1], cast({0} as json))", dc.ERROR_HISTORY.getType(), latestError)
just add spaces around the colon and it works correctly. note that i made another mistake by putting single quotes around {0}, because the latestError object is already of type JSON.

Related

Why single quote escape cannot be used in QuestDB, Error: dangling expression

I'm trying to use Query Variables in Grafana, the panel query source is PostgreSQL for QuestDB.
I have added the variable without any issue, but I'm unable to use the variable in Panel query since the variable values contains the spaces (SENSOR01 ON_OFF), also I'm unable to figure-out how to add single quote escape.
Following are the scenarios I tried:
Scenario1: this indicates due to space in the Variable value, on_off considered as separate word
where sensor_name = $sensor
db query error: pq: unexpected token: on_off
.
.
Scenario2: tried to add single quotes explicitly for the variable value, but there is generic error from source DB (QuestDB)
where sensor_name = concat('''', $sensor, '''')
db query error: pq: dangling expression
When tried Scenario2 approach directly in query of Variable, getting the same error
..
Scenario3: Hard-coded the variable value with space and with single quotes, but this giving me error with first part of the variable, looks like the hard-coded single quotes not passed here!
Error (Scenario3):
Is there any way/workaround to tackle this issue?
Could you just add the quotes directly in the query?
where sensor_name = '$sensor'
I have a similar grafana panel querying a questDB database using a variable and it works for me. This is my query:
select device_type, avg(duration_ms) as avg_duration_ms, avg(speed) as avg_speed, avg(measure1) as avg_m1, avg(measure2) as avg_m2 from ilp_test
WHERE
$__timeFilter(timestamp) and device_type = '$deviceType'
A rather hacky workaround would be to do:
where sensor_name = concat(cast(cast('&' as int) + 1 as char), $sensor, cast(cast('&' as int) + 1 as char))
This should work, but I'm pretty sure there is a better solution. Let me find it and get back to you.
Update. We may support Postgres syntax (which is '' escaping for a single quote char) in one of upcoming versions. For now, you'd have to use the above workaround.

Input string was not in correct formate while inserting data to postgresql through entityframework in .net core using dynamic query

I am getting error while inserting data to pgsql with .net core entity framework
error is Input string was not in correct format
this is my query executing
INSERT INTO public."MedQuantityVerification"("Id","MedId","ActivityBy","ActivityOn","Quantity","ActivityType","SupposedOn","Note") Values(7773866,248953,8887,'7/14/2018 10:43:43 PM','42.5 qty',5,NULL,'I counted forty two {point} five.')
anyhow when I run that query directly to postgresql browser it works fine
looks like issue on c# side it is but not know what?
also issue is with {point}
this is how I executing the dynamic query
db.Database.ExecuteSqlRaw(query);
You have to escape the curly brackets:
{point} should be {{point}}
ExecuteSqlRaw utilizes curly braces to parameterize the raw query so if your query naturally includes them like OP's does the function is going to try and parse them. Doubling up the braces like in Koen Schepens' answer acts as an escape sequence and tells the function not to parse it as a parameter.
The documentation for the function uses the following example as to the purpose of why it does what it does:
var userSuppliedSearchTerm = ".NET";
context.Database.ExecuteSqlRaw("UPDATE Blogs SET Rank = 50 WHERE Name = {0}", userSuppliedSearchTerm);
Note that you'll want to use this to your advantage any time you're accepting user-input and passing it to ExecuteSqlRaw. If the curly brace is in a parameter instead of the main string it doesn't need to be escaped.

SQLAlchemy Core - generating PostgreSQL SUBSTRING expression?

The syntax for SUBSTRING in PostgreSQL is SUBSTRING(<text_expr> FROM <i> FOR <j>). Any idea how to make SQLAlchemy core generate that? I'm trying sqlalchemy.sql.expression.func, but that expects typically comma-separated notation. I don't see a built-in Function that addresses this. I'm not quite sure if literal or text would work. Any thoughts?
Looking through the SqlAlchemy tests, I found that sqlalchemy.sql.expression.func.substring compiles to SUBSTRING for PSQL:
def test_substring(self):
self.assert_compile(
func.substring("abc", 1, 2),
"SUBSTRING(%(substring_1)s FROM %(substring_2)s "
"FOR %(substring_3)s)",
)
self.assert_compile(
func.substring("abc", 1),
"SUBSTRING(%(substring_1)s FROM %(substring_2)s)",
)
func.substring(str, from, [for]) is indeed what you want. It is "comma-delineated" because that's how Python methods
If you want to generate the SQL yourself, you could do something like text("SUBSTRING('foo' FROM 1 FOR 2)"), but I don't see why you would.

Pyspark: ValueError

I have a dictionary of PySpark RDDs and am trying to convert them to data frames, save them as variable and then join them. When I attempt to convert one of my RDDs to a data frame I get the following error:
File "./spark-1.3.1/python/pyspark/sql/types.py",
line 986, in _verify_type
"length of fields (%d)" % (len(obj), len(dataType.fields)))
ValueError: Length of object (52) does not match with length of fields (7)
Does anyone know what this exactly means or can help me with a work around?
I agree - we need to see more code - obfuscated data is fine.
You are using SparkQL it seems (sql types) - mapped onto what ? HDFS/Text
From the error it would appear that your create schema is incorrect - leading to an error - when to create a Data Frame.
This was due to the passing of an incorrect RDD, sorry everyone. I was passing the incorrect RDD which caused didn't fit the code I was using.

Connect to Access database from matlab

I was trying to connect to a Access database from matlab, by following the example given in matlab documentation
1 setdbprefs('DataReturnFormat','cellarray')
2 url = [['jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DSN='';DBQ='] dbpath];
3 con = database('','','','sun.jdbc.odbc.JdbcOdbcDriver', url);
4 sql = ['select * from ' table_name] ;
5 cursor = exec(con,sql);
6 cursor = fetch(cursor);
7 data.data = cursor.data;
I got the following error when I was requesting data from table A, at line 6, the error message was:
Error using cell
Size inputs must be integers.
Error in cursor/fetch (line 329)
outCursor.Data =
cell(rowLimit,
numberOfColumns);
I tried fetch data from other tables in the same database, it went without problem. What might be the issue?
Please refer to the documentation. fetch must be called with two parameters, connection and query and it returns the result, not a cursor.
Ok, I still hadn't got to the bottom of this yet, but retrieving the data incrementally worked for me, by setting the preference:
setdbprefs('FetchInBatches', 'yes');
setdbprefs('FetchBatchSize', '2');
#Daniel's answer also works fine, but it is difficult to get the column headers that way (let me know if you know how, I tried using another sql query but if did not work for me)...