40

I have used the next SQL statement in both MySQL and PostgreSQL:

db.Query(`SELECT COUNT(*) as N FROM email WHERE address = ?`, email)

But it fails in PostgreSQL with this error:

pq: F:"scan.l" M:"syntax error at end of input" S:"ERROR" C:"42601" P:"50" R:"scanner_yyerror" L:"993"

What's the problem? The error messages in PostgreSQL are very cryptic.

2
  • 2
    What language are you coding in? I mean the client language, not the SQL. Commented Oct 29, 2012 at 10:28
  • 1
    What database client are you using? That cryptic error is much more to do with the database client than the database server. If I prepare that statement it's fine, so the issue is most likely with your programming language or database adapter. Try it in psql. PREPARE q AS SELECT COUNT(*) as N FROM email WHERE address = $1; then EXECUTE q;. $1 is the placeholder syntax for PREPARE, but your programming language probably uses ?; otherwise there's no difference. Commented Oct 29, 2012 at 10:29

6 Answers 6

100

You haven't provided any details about the language/environment, but I'll try a wild guess anyway:

MySQL's prepared statements natively use ? as the parameter placeholder, but PostgreSQL uses $1, $2 etc. Try replacing the ? with $1 and see if it works:

WHERE address = $1

The error messages in PostgreSQL are very cryptic.

In general, I've found that Postgres error messages are better than competing products (ahem, MySQL and especially Oracle), but in this instance you've managed to confuse the parser beyond sanity. :)

Sign up to request clarification or add additional context in comments.

3 Comments

Note that this is dependent on the programming language and database access driver used. In JDBC, for example, placeholders are always ?. The idea of having different placeholders based on DB driver is pretty horrid.
@CraigRinger, but forcing each driver to understand a specific placeholder (say, ?) forces the client side to implement full SQL parser matching that of the target DB engine. Moreover, $N potentially allows you to specify one value for several placeholders while ? does not.
@CraigRinger Finding the instances of ? is easy. But it's a hell of a lot harder if you consider that ? is a valid character within strings -- and shouldn't be changed there! Coupled with all the possible different escaping rules, which depend on server-side settings and Postgres versions, along with some pretty complicated parsing cases involving PostgreSQL's $foo$?$foo$ syntax. It gets VERY nasty.
17

In golang for queries we have use

  • MySQL uses the ? variant
  • PostgreSQL uses an enumerated $1, $2, etc bindvar syntax
  • SQLite accepts both ? and $1 syntax
  • Oracle uses a :name syntax

1 Comment

So the source of the error OP was seeing (I'm assuming he's moved on by now) was incorrect use of syntax for bind variables? It might be good to add a bit more detail to your answer.
9

You are using Go right?

try:

db.Query(`SELECT COUNT(*) as N FROM email WHERE address = $1`, email)

1 Comment

This worked for me too. Way to fill in where the docs were missing.
6

In my case, it was due to using a -- line comment where the program that was responsible for interacting with the database read in the multiple lines of my query all as one giant line. This meant that the line comment corrupted the remainder of the query. The fix was to use a /* block comment */ instead.

Comments

1

Another possibility - check for any missing END directives for IF, LOOP, etc.

I'd been working in a loop so long, that I didn't realize I never put in an END LOOP;.

The message that Postgres displays:

ERROR:  syntax error at end of input
LINE 123: $$;

is terribly unhelpful at telling you if some construct was never closed.

Comments

0

One cause for this error can be that you are missing a terminating semi-colon before your final END statement, for example

return True
END;
$$
LANGUAGE plpgsql;

which should be

return True;
END;
$$
LANGUAGE plpgsql;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.