#22401 closed Bug (duplicate)
SQL Function initial SQL data does not work.
Reported by: | Julien GODIN | Owned by: | nobody |
---|---|---|---|
Component: | Core (Management commands) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I created a model and trying to add some functions to it :
Full trace :
Failed to install custom SQL for frontend.Alarm model: unterminated dollar-quoted string at or near "$$ BEGIN RETURN + 1;" LINE 1: ... FUNCTION increment(i integer) RETURNS integer AS $$ BEGIN R...
Here is the function I am trying to create :
( stolen from here : http://www.postgresql.org/docs/9.1/static/sql-createfunction.html )
CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$ BEGIN RETURN i + 1; END; $$ LANGUAGE plpgsql;
The problem is in the _split_statements(content) function where it checks if the lines ends with ";" and close the statement if so.
The problem is that PLSQL functions needs ";" to work.
Attachments (1)
Change History (15)
by , 11 years ago
Attachment: | patch.patch added |
---|
comment:1 by , 11 years ago
Component: | Uncategorized → Core (Management commands) |
---|---|
Patch needs improvement: | set |
Triage Stage: | Unreviewed → Accepted |
Type: | Uncategorized → Bug |
Hardcoding CREATE and LANGUAGE doesn't sound like a good solution. What if there's simply a ; at the end of a line in a multi-line string?
Parsing SQL with regex is worse than parsing HTML with regex... If we want to fix these edge cases, we must fix them with proper parsing, not hacks.
comment:2 by , 11 years ago
So, to provide a summary of the situation :
- No regex.
- parse the SQL properly.
Should we be using this ? :
http://code.google.com/p/python-sqlparse/
as i do not see any other solution so far.
comment:3 by , 11 years ago
Actually sqlparse is here now: https://github.com/andialbrecht/sqlparse
It supports Python 2.5+ and 3.2+, which is good, and provides the exact feature we need:
https://sqlparse.readthedocs.org/en/latest/api/?highlight=split#sqlparse.split
I'm +0 on introducing this as on optional dependency and +1 on deprecating the current regex-based logic and eventually turning it into a mandatory dependency when you want to load initial SQL (which most projects don't)!
comment:4 by , 11 years ago
+1 on deprecating regex SQL parsing. I don't think we should be maintaining any other half-baked solution to SQL parsing either. So, I guess that makes me +1 on requiring sqlparse for initial SQL.
comment:5 by , 11 years ago
Proposed a pull request here :
https://github.com/django/django/pull/2529
It remove the regex technique and uses sqlparse.
comment:6 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:7 by , 11 years ago
Has patch: | unset |
---|---|
Patch needs improvement: | unset |
Resolution: | fixed |
Severity: | Normal → Release blocker |
Status: | closed → new |
Version: | 1.6 → master |
There's a regression here because sqlparse
does not strip trailing comments the way the regex does (see #4680 for when this behavior was added). tests/initial_sql_regress/sql/simple.sql
contains a trailing comment on line 2 and this causes MySQL to error out with "Commands out of sync; you can't run this command now". Jenkins doesn't have sqlparse
installed, so it's still using the regex logic.
You can reproduce this behavior with the following code:
>>> from django.db import connection >>> cursor = connection.cursor() >>> cursor.execute("SELECT 1; --") >>> cursor.execute("SELECT 2;") Traceback ... django.db.utils.ProgrammingError: (2014, "Commands out of sync; you can't run this command now")
I've realized that initial SQL data is deprecated (pending confirmation from Andrew Godwin in #22444) so I'm inclined just to revert this and mark it "won't fix".
comment:8 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:9 by , 11 years ago
Resolution: | fixed |
---|---|
Status: | closed → new |
comment:10 by , 11 years ago
Possible solution:
>>> import sqlparse >>> sqlparse.split(""" ... SELECT 1; -- comment ... SELECT 2; ... """) ['SELECT 1; -- comment', 'SELECT 2;', ''] >>> [sqlparse.format(stmt, strip_comments=True) for stmt in _ if stmt] ['SELECT 1;', 'SELECT 2;']
comment:11 by , 11 years ago
Aymeric, you think it's worth addressing this even though the feature is deprecated?
comment:12 by , 11 years ago
Resolution: | → duplicate |
---|---|
Severity: | Release blocker → Normal |
Status: | new → closed |
This is really a duplicate of #3214.
Potential patch