Yes, there is such limitation.
EXECUTE 'SELECT aColumn FROM $1' USING tableVar;
will not work.
You cannot use parameters for table/column names - that's because PostgerSQL query parser must identify all used tables in order to compile the query.
Quote from PL/pgSQL docs about dynamic SQL commands:
Note that parameter symbols can only be used for data values — if you
want to use dynamically determined table or column names, you must
insert them into the command string textually. For example, if the
preceding query needed to be done against a dynamically selected
table, you could do this:
EXECUTE 'SELECT count(*) FROM '
|| tabname::regclass
|| ' WHERE inserted_by = $1 AND inserted <= $2'
INTO c
USING checked_user, checked_date;
As noted in comments below, the cast method is not always feasible, especially for CREATE statements. Better use the format(formatstr, *formatarg) function:
EXECUTE format(
'CREATE TABLE %I (%I %I, %I %I)',
v_tabname,
v_col1name, v_col1type,
v_col2name, v_col2type);
Side note: this limitation comes from SQL language itself. Parser needs to know table/column names to resolve if query text is correct or not.
Hence it applies to dynamic SQL in other DBMS-es, Oracle for example: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/dynamic.htm#CHDHGHIF
execute ... usingcan only use substitutions where you could normally have bind variables - ie not for table names etcquote_ident- such as restrict to~'^[a-z]{3,10}$'and add a prefix