EXECUTE of SELECT ... INTO is not implemented

Instead of

execute 'select 1 into i'    -- error

you should use

execute 'select 1' into i

The error message is the least of the problems in this function. Consider a complete rewrite.

Assuming the column date is actually data type date:

CREATE OR REPLACE FUNCTION create_partition_and_insert()
  RETURNS trigger AS
$func$
DECLARE
   _partition text := quote_ident(TG_RELNAME
                               || to_char(NEW.date,'_YYYY_MM_DD"p"'));
BEGIN
   IF NOT EXISTS(SELECT relname FROM pg_class WHERE relname = _partition) THEN
      EXECUTE format('CREATE TABLE %s (CHECK (date = %L)) INHERITS (%I);'
                   , _partition, NEW.date, TG_RELNAME);

      RAISE NOTICE 'A new partition has been created: %', _partition;
   END IF;

   EXECUTE format('INSERT INTO %s SELECT ($1).*', _partition)
   USING NEW;

   RETURN NULL;
END
$func$  LANGUAGE plpgsql;

Major points

  • You don't need dynamic SQL in your first statement at all (the source or your syntax error). Actually, you don't need the whole statement nor the variable. I radically simplified the name concatenation. Details for to_char() in the manual.

  • Ignoring the typographical quotes in ‘p’ - those are probably just c/p artefacts.

  • Assignments are comparatively expensive in plpgsql. Adapt your programming style and reduce variables and assignments.

  • Don't convert the whole row to its text representation, concatenate and then cast it back. That's needlessly expensive, convoluted and error-prone. Pass the value directly in a USING clause to EXECUTE like demonstrated.

  • Don't raise the notice before it's done. RAISE is not rolled back in the case of an exception leading to potentially misleading log entries.

  • If you have more than one schema in your database (which is common), your code is still unsafe. You need to schema-qualify table names or SET the search_path for the function.

Related answers with more details:

  • How to check if a table exists in a given schema

  • Creating a trigger for child table insertion returns confusing error

  • INSERT with dynamic table name in trigger function

  • How does the search_path influence identifier resolution and the "current schema"