src/bin/psql/command.c
static backslashResult
exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
				   PQExpBuffer query_buf, bool is_func)
{
	backslashResult status = PSQL_CMD_SKIP_LINE;

	if (active_branch)
	{
		char	   *obj_desc = psql_scan_slash_option(scan_state,
													  OT_WHOLE_LINE,
													  NULL, true);
		int			lineno = -1;

		if (!query_buf)
		{
			pg_log_error("no query buffer");
			status = PSQL_CMD_ERROR;
		}
		else
		{
			Oid			obj_oid = InvalidOid;
			EditableObjectType eot = is_func ? EditableFunction : EditableView;

			lineno = strip_lineno_from_objdesc(obj_desc);
			if (lineno == 0)
			{
				/* error already reported */
				status = PSQL_CMD_ERROR;
			}
			else if (!obj_desc)
			{
				/* set up an empty command to fill in */
				resetPQExpBuffer(query_buf);
				if (is_func)
					appendPQExpBufferStr(query_buf,
										 "CREATE FUNCTION ( )\n"
										 " RETURNS \n"
										 " LANGUAGE \n"
										 " -- common options:  IMMUTABLE  STABLE  STRICT  SECURITY DEFINER\n"
										 "AS $function$\n"
										 "\n$function$\n");
				else
					appendPQExpBufferStr(query_buf,
										 "CREATE VIEW  AS\n"
										 " SELECT \n"
										 "  -- something...\n");
			}
			else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
			{
				/* error already reported */
				status = PSQL_CMD_ERROR;
			}
			else if (!get_create_object_cmd(eot, obj_oid, query_buf))
			{
				/* error already reported */
				status = PSQL_CMD_ERROR;
			}
			else if (is_func && lineno > 0)
			{
				/*
				 * lineno "1" should correspond to the first line of the
				 * function body.  We expect that pg_get_functiondef() will
				 * emit that on a line beginning with "AS ", and that there
				 * can be no such line before the real start of the function
				 * body.  Increment lineno by the number of lines before that
				 * line, so that it becomes relative to the first line of the
				 * function definition.
				 */
				const char *lines = query_buf->data;

				while (*lines != '\0')
				{
					if (strncmp(lines, "AS ", 3) == 0)
						break;
					lineno++;
					/* find start of next line */
					lines = strchr(lines, '\n');
					if (!lines)
						break;
					lines++;
				}
			}
		}

		if (status != PSQL_CMD_ERROR)
		{
			bool		edited = false;

			if (!do_edit(NULL, query_buf, lineno, true, &edited))
				status = PSQL_CMD_ERROR;
			else if (!edited)
				puts(_("No changes"));
			else
				status = PSQL_CMD_NEWEDIT;
		}

		if (obj_desc)
			free(obj_desc);
	}
	else
		ignore_slash_whole_line(scan_state);

	return status;
}
/*
 * \ef/\ev -- edit the named function/view, or
 * present a blank CREATE FUNCTION/VIEW template if no argument is given
 */
\ef/\ev -- edit the named function/view, or
present a blank CREATE FUNCTION/VIEW template if no argument is given
\ ef / \ ev -- edit the named function / view or present a blank CREATE FUNCTION / VIEW template if no argument is given
static backslashResult
exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
				   PQExpBuffer query_buf, bool is_func)
{
	backslashResult status = PSQL_CMD_SKIP_LINE;
	if (active_branch)
	{
		char	   *obj_desc = psql_scan_slash_option(scan_state,
													  OT_WHOLE_LINE,
													  NULL, true);
		int			lineno = -1;
		if (!query_buf)
		{
			pg_log_error("no query buffer");
			status = PSQL_CMD_ERROR;
		}
		else
		{
			Oid			obj_oid = InvalidOid;
			EditableObjectType eot = is_func ? EditableFunction : EditableView;
			lineno = strip_lineno_from_objdesc(obj_desc);
			if (lineno == 0)
			{
				status = PSQL_CMD_ERROR;
			}
			else if (!obj_desc)
			{
				resetPQExpBuffer(query_buf);
				if (is_func)
					appendPQExpBufferStr(query_buf,
										 "CREATE FUNCTION ( )\n"
										 " RETURNS \n"
										 " LANGUAGE \n"
										 " -- common options:  IMMUTABLE  STABLE  STRICT  SECURITY DEFINER\n"
										 "AS $function$\n"
										 "\n$function$\n");
				else
					appendPQExpBufferStr(query_buf,
										 "CREATE VIEW  AS\n"
										 " SELECT \n"
										 "  -- something...\n");
			}
			else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
			{
				status = PSQL_CMD_ERROR;
			}
			else if (!get_create_object_cmd(eot, obj_oid, query_buf))
			{
				status = PSQL_CMD_ERROR;
			}
			else if (is_func && lineno > 0)
			{
				const char *lines = query_buf->data;
				while (*lines != '\0')
				{
					if (strncmp(lines, "AS ", 3) == 0)
						break;
					lineno++;
					lines = strchr(lines, '\n');
					if (!lines)
						break;
					lines++;
				}
			}
		}
		if (status != PSQL_CMD_ERROR)
		{
			bool		edited = false;
			if (!do_edit(NULL, query_buf, lineno, true, &edited))
				status = PSQL_CMD_ERROR;
			else if (!edited)
				puts(_("No changes"));
			else
				status = PSQL_CMD_NEWEDIT;
		}
		if (obj_desc)
			free(obj_desc);
	}
	else
		ignore_slash_whole_line(scan_state);
	return status;
}
static backslashResult exec_command_ef_ev ( PsqlScanState scan_state , bool active_branch , PQExpBuffer query_buf , bool is_func ) { backslashResult status = PSQL_CMD_SKIP_LINE ; if ( active_branch ) { char * obj_desc = psql_scan_slash_option ( scan_state , OT_WHOLE_LINE , NULL , true ) ; int lineno = -1 ; if ( ! query_buf ) { pg_log_error ( " " ) ; status = PSQL_CMD_ERROR ; } else { Oid obj_oid = InvalidOid ; EditableObjectType eot = is_func ? EditableFunction : EditableView ; lineno = strip_lineno_from_objdesc ( obj_desc ) ; if ( lineno == 0 ) { status = PSQL_CMD_ERROR ; } else if ( ! obj_desc ) { resetPQExpBuffer ( query_buf ) ; if ( is_func ) appendPQExpBufferStr ( query_buf , " \n " " \n " " \n " " \n " " \n " " \n \n " ) ; else appendPQExpBufferStr ( query_buf , " \n " " \n " " \n " ) ; } else if ( ! lookup_object_oid ( eot , obj_desc , & obj_oid ) ) { status = PSQL_CMD_ERROR ; } else if ( ! get_create_object_cmd ( eot , obj_oid , query_buf ) ) { status = PSQL_CMD_ERROR ; } else if ( is_func && lineno > 0 ) { const char * lines = query_buf -> data ; while ( * lines != ' \0 ' ) { if ( strncmp ( lines , " " , 3 ) == 0 ) break ; lineno ++ ; lines = strchr ( lines , ' \n ' ) ; if ( ! lines ) break ; lines ++ ; } } } if ( status != PSQL_CMD_ERROR ) { bool edited = false ; if ( ! do_edit ( NULL , query_buf , lineno , true , & edited ) ) status = PSQL_CMD_ERROR ; else if ( ! edited ) puts ( _ ( " " ) ) ; else status = PSQL_CMD_NEWEDIT ; } if ( obj_desc ) free ( obj_desc ) ; } else ignore_slash_whole_line ( scan_state ) ; return status ; }
\ef/\ev -- edit the named function/view, or
 present a blank CREATE FUNCTION/VIEW template if no argument is given
\ ef / \ ev -- edit the named function / view or present a blank CREATE FUNCTION / VIEW template if no argument is given
/* error already reported */ /* set up an empty command to fill in */ /* error already reported */ /* error already reported */ /*
				 * lineno "1" should correspond to the first line of the
				 * function body.  We expect that pg_get_functiondef() will
				 * emit that on a line beginning with "AS ", and that there
				 * can be no such line before the real start of the function
				 * body.  Increment lineno by the number of lines before that
				 * line, so that it becomes relative to the first line of the
				 * function definition.
				 */ /* find start of next line */