SQL runs on localhost but throws SQLSTATE[42883] error on deployment to heroku - mysql

i have a laravel/vuejs project i just deployed to heroku. Everything works well both on local and production except for a query that is throwing up SQLSTATE[42883] error on production. The sql query retrieves a count of models created every week:
public function getProductWeeklyData(){
$products= Product::selectRaw('COUNT(*) AS product_count')
->selectRaw('FROM_DAYS(TO_DAYS(created_at) -MOD(TO_DAYS(created_at) -1, 7)) AS week_starting')
->groupBy('week_starting')
->orderBy('week_starting')
->take(10)->get();
$products->each->setAppends([]);
return response()->json($products, 200);
}
This works on localhost and return an array like so:
0: {product_count: 7, week_starting: "2021-10-31"}
1: {product_count: 12, week_starting: "2021-11-07"}
2: {product_count: 15, week_starting: "2021-11-14"}
which was exactly what i wanted.
However, after deploying to heroku and changing the database connection to PostgreSQL, the query fails and start returning this error.
"message": "SQLSTATE[42883]: Undefined function: 7 ERROR: function to_days(timestamp without time zone) does not exist\nLINE 1: select COUNT() AS product_count,FROM_DAYS(TO_DAYS(created_at...\n ^\nHINT: No function matches the given name and argument types. You might need to add explicit type casts. (SQL: select COUNT() AS product_count, FROM_DAYS(TO_DAYS(created_at) -MOD(TO_DAYS(created_at) -1, 7)) AS week_starting from "products" group by "week_starting" order by "week_starting" asc limit 10)"
i tried casting the date like was suggested in the error by doing this
...(created_at::text, 'YYYY-MM-DD')
but still got an error of invalid query.
How do i get this query working with PostgreSQL on production?

Related

JPQL 'Function' doesn't send operator

I am using EclipseLink over Spring Boot and have this jpql in a repository:
#Query("select function('pMonth',p.payDay) ,sum(p.price) " +
"from FullPayment p where " +
"group by function('pMonth', p.payDay)"
)
List<Object[]> paymentMonthlyHistory();
but it does not send the operator p.payDay calling my custom function pMonth. Here is the database error:
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Incorrect number of arguments for FUNCTION adventure_db.pMonth; expected 1, got 0
Error Code: 1318
Call: SELECT pMonth(), SUM(PRICE) FROM panel_fullPayment WHERE ((PAYDATE >= ?) AND (TRANSACTIONAMOUNT >= PRICE)) GROUP BY pMonth()
bind => [1 parameter bound]
I use Mysql as DBMS. Any help would be appreciated
The problem was a typo. The field name is payDate but I wrote p.payDay. I put the answer here to emphasize that if you mistype the field name here, it won't show you an error on boot, but will generate a wrong query.

Sequelize cast in MAX causes TypeError: smth.col.startsWith

I use sequelize 5, mysql2 in a node 10 and having mysql as dialect
The logic is that I want to get a max datetime from a table, but get it only as date, not the time part, so obviously I will cast the attribute to DATEONLY
My query is
Events.max(Sequelize.cast(Sequelize.col('eventTime'), 'DATEONLY'))
.then((result)=>{
console.log('eventTime ', result);
resolved(result.results);
})
and I get the error :
UnhandledPromiseRejectionWarning: TypeError: smth.col.startsWith is
not a function
If I remove the cast part and the query is like so
Events.max('eventTime')
.then((result)=>{
console.log('eventTime ', result);
resolved(result.results);
})
then this works fine.
How can I fix this? Thanks

Linq query with Take() to Mysql does not add limit to actual query

I am using net core 2.2 with Pomelo EntityFramework with MySql database.
The following code:
return context.SomeTable
.OrderByDescending(item => item.ExpiredTime)
.Where(item => item.FinishedTime.HasValue
&& item.ExpiredTime.HasValue
&& item.ExpiredTime.Value < DateTime.UtcNow
&& item.IsArchive.GetValueOrDefault(false) == false/* is null or false*/)
.Take(500)
.Select(i=>new ItemWrapper(i))
.ToArray();
Returns the following MySql:
SELECT `item`.`Id`, `item`.`ExpiredTime`, `item`.`FinishedTime`,
`item`.`IsArchive`
FROM `SomeTable` AS `item`
WHERE (`item`.`FinishedTime` IS NOT NULL AND `item`.`ExpiredTime` IS NOT
NULL) AND (`item`.`ExpiredTime` < UTC_TIMESTAMP())
ORDER BY `item`.`ExpiredTime` DESC
It seems like the Take(500) is not being reflected in the query.
I expect to see limit = 500 in the sql query.
Edit 1:
I am using Select(i=>new ItemWrapper(i) to create a new class for the result object, it seems to be the root of the issue.
What am i doing wrong?
This happens because you are calling item.IsArchive.GetValueOrDefault(false) == false in Where clause. EF.Core cannot translate this method to SQL so it materializes all the items first and then tries to apply the rest to the data retrieved from SQL server. Try to remove this condition or rewrite it. BTW, usually EF.Core shows warnings for these kind of issues in the log.

Update Statement with filter, sortBy, map and take

I am writing the following update statement against a MySql database:
Orders.filter(_.cookie === cookie).sortBy(_.id.desc).map(_.payTypeId).take(1)
sortBy and take(1) are being used to ensure I'm only updating the most recent order for a particular cookie. This query works fine as a regular SELECT, this issue here is using it as an update statement.
The error I'm getting:
[SlickException: A query for an UPDATE statement must resolve to a comprehension with a single table -- Unsupported shape: Comprehension s2, Some(Apply Function =), None, ConstArray((Path s2.id,Ordering(Desc,NullsDefault))), None, None, Some(LiteralNode 1 (volatileHint=false)), None, false]
If I remove the take(1) clause, everything works fine. Why I am I getting this error?
Github seems to have a discussion about this, with no solution.
Workaround using plain SQL
(This query returns a Vector[Int])
val updateQuery =
sql"""
UPDATE
orders
SET
orders.pay_type_id = $id
WHERE
orders.cart_cookie = $cookie
ORDER BY id desc
LIMIT 1
""".as[Int]

Simple difficulty with HQL Query

I am having a trouble with executing an HQL query like this:
select new myPackage.view.CoverDocumentReportView(Re.code AS fulCd,
Re.creditPrice AS crtprc,
Re.debitPrice AS dbtprc,
(Re.debitPrice - Re.debitPrice) AS redbtprc,
(Re.creditPrice- Re.creditPrice) AS recrtprc,
(Re.debitPrice-Re.creditPrice) AS rem)
from
(select fullCode as code,
sum(creditPrice) as creditPrice ,
sum(debitPrice) as debitPrice
from DocumentMaster DM,
DocumentAccount DA,
Tree T ,
AccountTree AT,
DocumentDetailed DD
where DM.id = DA.documentMaster and
DA.accountTree = T.id and
DA.accountTree = AT.id and
DD.documentAccount = DA.id
group by DA.accountTree ) As Re
1)
If I execute this like:
SQLQuery crit = (SQLQuery) session
.createSQLQuery(sql).setResultTransformer(Transformers.aliasToBean(CoverDocumentReportView.class));
ArrayList<CoverDocumentReportView> li = (ArrayList<CoverDocumentReportView>) crit.list();
ERROR 2012-12-22 14:16:19,838 [http-8080-1] org.hibernate.util.JDBCExceptionReporter : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.datx.web.accounting.view.CoverDocumentReportView(Re.code AS fulCd,
Re.creditP' at line 1
2)
If I execute it with this:
Query query = session.createQuery(sql).setResultTransformer(Transformers.aliasToBean(CoverDocumentReportView.class));
ArrayList<CoverDocumentReportView> li = (ArrayList<CoverDocumentReportView>)query.list();
The error will be:
ERROR 2012-12-22 14:51:46,709 [http-8080-1] org.hibernate.hql.ast.ErrorCounter : line 1:224: unexpected token: (
ERROR 2012-12-22 14:51:46,709 [http-8080-1] org.hibernate.hql.ast.ErrorCounter : line 1:308: unexpected token: sum
What is the problem?
SQL and HQL are two different languages.
HQL doesn't support subqueries in from clauses, so this query can't be an HQL query.
And SQL doesn't know about Java objects, and doesn't have any new() function allowing to create them, so the query is not a valid SQL query either.
Make it a valid SQL query, execute it using createSQLQuery(), then iterate through the results and create instances of your objects from the returned rows. Or use a result transformer as you're doing, which will do that for you. the result transformer will use the aliases you assigned to the returned columns of the SQL query to create beans for you. You don't need any new CoverDocumentReportView() in the query to make that work. Read the javadoc for details.