I am using strapi and postgres. I created two collections in strapi called «solutions» and «references».
When I run dt
I get the following output:
...more tables
public | references | table | postgres
public | references_components | table | postgres
public | references_pages | table | postgres
public | references_pages_components | table | postgres
public | solutions | table | postgres
public | solutions_components | table | postgres
public | solutions_pages | table | postgres
public | solutions_pages_components
Now I want to run a SELECT
on table «solutions», which works:
SELECT * FROM solutions;
But when I run SELECT * FROM references;
I get:
ERROR: syntax error at or near "references"
LINE 1: SELECT * FROM references;
I already checked if there is a lock, but nothing. Running z references
gives the following output:
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+---------------------------+-------------------+----------
public | references | table | postgres=arwdDxt/postgres | |
(1 row)
What could be wrong? Is there maybe an issue with the table being named «references»? This issue happens on my local machine as well on our staging server, so I do not assume that it is an issue with my local postgres setup.
I also checked priviliges with
SELECT table_catalog, table_schema, table_name, privilege_type
FROM information_schema.table_privileges WHERE grantee = 'postgres'
Which gives this output (scroll to the right):
mytable | public | references | INSERT
mytable | public | references | SELECT
mytable | public | references | UPDATE
mytable | public | references | DELETE
mytable | public | references | TRUNCATE
mytable | public | references | REFERENCES
mytable | public | references | TRIGGER
Syntax errors are quite common while coding.
But, things go for a toss when it results in website errors.
PostgreSQL error 42601 also occurs due to syntax errors in the database queries.
At Bobcares, we often get requests from PostgreSQL users to fix errors as part of our Server Management Services.
Today, let’s check PostgreSQL error in detail and see how our Support Engineers fix it for the customers.
What causes error 42601 in PostgreSQL?
PostgreSQL is an advanced database engine. It is popular for its extensive features and ability to handle complex database situations.
Applications like Instagram, Facebook, Apple, etc rely on the PostgreSQL database.
But what causes error 42601?
PostgreSQL error codes consist of five characters. The first two characters denote the class of errors. And the remaining three characters indicate a specific condition within that class.
Here, 42 in 42601 represent the class “Syntax Error or Access Rule Violation“.
In short, this error mainly occurs due to the syntax errors in the queries executed. A typical error shows up as:
Here, the syntax error has occurred in position 119 near the value “parents” in the query.
How we fix the error?
Now let’s see how our PostgreSQL engineers resolve this error efficiently.
Recently, one of our customers contacted us with this error. He tried to execute the following code,
CREATE OR REPLACE FUNCTION prc_tst_bulk(sql text)
RETURNS TABLE (name text, rowcount integer) AS
$$
BEGIN
WITH m_ty_person AS (return query execute sql)
select name, count(*) from m_ty_person where name like '%a%' group by name
union
select name, count(*) from m_ty_person where gender = 1 group by name;
END
$$ LANGUAGE plpgsql;
But, this ended up in PostgreSQL error 42601. And he got the following error message,
ERROR: syntax error at or near "return"
LINE 5: WITH m_ty_person AS (return query execute sql)
Our PostgreSQL Engineers checked the issue and found out the syntax error. The statement in Line 5 was a mix of plain and dynamic SQL. In general, the PostgreSQL query should be either fully dynamic or plain. Therefore, we changed the code as,
RETURN QUERY EXECUTE '
WITH m_ty_person AS (' || sql || $x$)
SELECT name, count(*)::int FROM m_ty_person WHERE name LIKE '%a%' GROUP BY name
UNION
SELECT name, count(*)::int FROM m_ty_person WHERE gender = 1 GROUP BY name$x$;
This resolved the error 42601, and the code worked fine.
[Need more assistance to solve PostgreSQL error 42601?- We’ll help you.]
Conclusion
In short, PostgreSQL error 42601 occurs due to the syntax errors in the code. Today, in this write-up, we have discussed how our Support Engineers fixed this error for our customers.
PREVENT YOUR SERVER FROM CRASHING!
Never again lose customers to poor server speed! Let us help you.
Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.
GET STARTED
var google_conversion_label = «owonCMyG5nEQ0aD71QM»;
Last tested: Feb 2021
Overview
This SQL error generally means that somewhere in the query, there is invalid syntax.
Some common examples:
- Using a database-specific SQL for the wrong database (eg BigQuery supports DATE_ADD, but Redshift supports DATEADD)
- Typo in the SQL (missing comma, misspelled word, etc)
- Missing a sql clause (missed from, join, select, etc)
- An object does not exist in the database or is not accessible from the current query (eg referencing orders.id when there is no orders table joined in the current query, etc)
In some circumstances, the database error message may display extra detail about where the error was raised, which can be helpful in narrowing down where to look.
Error Message
SQL ERROR: syntax error at or near
Troubleshooting
This should generally be the first step to troubleshoot any SQL syntax error in a large query: iteratively comment out blocks of SQL to narrow down where the problem is.
TIP: To make this process easier, change the group by clause to use position references
eg: group by 1,2,3,4,5 instead of group by orders.status, orders.date, to_char(...)...
as well as separate the where and having clauses onto multiple lines.
So for example, say we have the following query:
play_arrow
WITH cte AS (
select id, status, sales_amountfrom orders
)
select status, foo.date, sum(cte.sales_amount), count(*) from cte
join foo on cte.date = foo.date
group by status, foo.date
order by 3 desc
We could start by running just the portion in the CTE:
play_arrow
-- WITH cte AS (
select id, status, sales_amountfrom orders
-- )
-- select status, foo.date, sum(cte.sales_amount), count(*)
-- from cte
-- join foo on cte.date = foo.date
-- group by 1, 2
-- order by 3 desc
Then strip out the aggregates and portions related to them
play_arrow
WITH cte AS (
select id, status, sales_amountfrom orders
)
select status, foo.date, -- sum(cte.sales_amount), count(*)
from cte
join foo on cte.date = foo.date
-- group by 1, 2
-- order by 3 desc
Iteratively stripping out / adding back in portions of the query until you find the minimum query to trigger the error.
-
Lookup functions and syntax If the query is small enough, or if we’ve narrowed the scope enough with 1, google all the functions used in the query and verify that they exist and are being used correctly.
-
Verify all objects exist Verify that you’ve joined all tables used in the select, where, and having clause, and that those tables exist in the db. Once we’ve narrowed things down from 1, also check that each column exists in the table specified.
While setting up a test database on my system, I discovered the need to ALTER
existing FOREIGN KEY
‘s. Here’s what I studied, learned, and implemented.
Note: All data, names or naming found within the database presented in this post, are strictly used for practice, learning, instruction, and testing purposes. It by no means depicts actual data belonging to or being used by any party or organization.
I will be using Xubuntu Linux 16.04.3 LTS (Xenial Xerus) and PostgreSQL 10.2 for these exercises.
Steps
We will follow this order to update the FOREIGN KEY
‘s.
- Use
ALTER TABLE
command to drop any existingFOREIGN KEY
‘s. - Use
ALTER TABLE
command to add the neededFOREIGN KEY
‘s back to the table. - Verify new keys are in place and updated.
Current Structure.
With the below table structure, we can see three FOREIGN KEY
constraints.
fab_tracking=> d pipe_kind;
Table «public.pipe_kind»
Column | Type | Collation | Nullable | Default
————+———+————+———-+———
k_pipe_id | integer | | |
k_kind_id | integer | | |
Foreign—key constraints:
«k_pipe_fk» FOREIGN KEY (k_pipe_id) REFERENCES pipe(pipe_id)
«kind_fk» FOREIGN KEY (k_kind_id) REFERENCES kind_type(kind_id)
«pipe_kind_k_pipe_id_fkey» FOREIGN KEY (k_pipe_id) REFERENCES pipe(pipe_id)
Yet, I need to change the definitions and specify an ON UPDATE CASCADE ON DELETE CASCADE
‘contract’ for each constraint.
How can I do that?
After reading this informative blog post, I decided to use the demonstrated examples there, and apply them to my own needs.
Implementing the Changes.
All changes are built upon the ALTER TABLE
command.
But, in order to make them, we need to DROP
, those existing keys first:
fab_tracking=> ALTER TABLE pipe_kind DROP CONSTRAINT k_pipe_fk;
ALTER TABLE
Next, we can reuse that same FOREIGN KEY
constraint name again, in a follow-up ALTER TABLE
command. This time, specifying those ON DELETE CASCADE ON UPDATE CASCADE
options we need.
fab_tracking=> ALTER TABLE pipe_kind ADD CONSTRAINT k_pipe_fk FOREIGN KEY (k_pipe_id) REFERENCES pipe(pipe_id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE
Easily enough, we just repeat the same process for the two remaining FOREIGN KEY
‘s.
fab_tracking=> ALTER TABLE pipe_kind DROP CONSTRAINT kind_fk;
ALTER TABLE
To receive notifications for the latest post from “Digital Owl’s Prose” via email, please subscribe by clicking the ‘Click To Subscribe!’ button in the sidebar!
Be sure and visit the “Best Of” page for a collection of my best blog posts.
fab_tracking=> ALTER TABLE pipe_kind ADD CONSTRAINT kind_fk FOREIGN KEY (k_kind_id) REFERENCES kind_type(kind_id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE
fab_tracking=> ALTER TABLE pipe_kind DROP CONSTRAINT pipe_kind_k_pipe_id_fkey;
ALTER TABLE
fab_tracking=> ALTER TABLE pipe_kind ADD CONSTRAINT pipe_kind_k_pipe_id_fkey FOREIGN KEY(k_pipe_id) REFERENCES pipe(pipe_id) ON DELETE CASCADE ON UPDATE ;
ERROR: syntax error at or near «;»
LINE 1: …e_id) references pipe(pipe_id) on delete cascade on update ;
^
(Ooops… Left out the CASCADE
keyword for that one. Let’s try that again.)
fab_tracking=> ALTER TABLE pipe_kind ADD CONSTRAINT pipe_kind_k_pipe_id_fkey FOREIGN KEY(k_pipe_id) REFERENCES pipe(pipe_id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE
That’s better.
Here’s the final description of the pipe_kind
table with all altered FOREIGN KEY
constraints in place.
1 |
fab_tracking=> d pipe_kind; |
Try Them Yourself
I hope through this blog post and the linked article, you can change existing FOREIGN KEY
‘s in your tables as needed.
A Call To Action!
Thank you for taking the time to read this post. I truly hope you discovered something interesting and enlightening. Please share your findings here, with someone else you know who would get the same value out of it as well.
Visit the Portfolio-Projects page to see blog post/technical writing I have completed for clients.
Have I mentioned how much I love a cup of coffee?!?!
To receive notifications for the latest post from “Digital Owl’s Prose” via email, please subscribe by clicking the ‘Click To Subscribe!’ button in the sidebar!
Be sure and visit the “Best Of” page for a collection of my best blog posts.
Josh Otwell has a passion to study and grow as a SQL Developer and blogger. Other favorite activities find him with his nose buried in a good book, article, or the Linux command line. Among those, he shares a love of tabletop RPG games, reading fantasy novels, and spending time with his wife and two daughters.
Disclaimer: The examples presented in this post are hypothetical ideas of how to achieve similar types of results. They are not the utmost best solution(s). The majority, if not all, of the examples provided are performed on a personal development/learning workstation-environment and should not be considered production quality or ready. Your particular goals and needs may vary. Use those practices that best benefit your needs and goals. Opinions are my own.