Hi Pavel,

On Sat, Sep 5, 2015 at 12:36 AM, Pavel Stehule <pavel.steh...@gmail.com>
wrote:

>
>
> 2015-09-05 8:35 GMT+02:00 dinesh kumar <dineshkuma...@gmail.com>:
>
>>
>>
>> On Fri, Sep 4, 2015 at 2:03 PM, Pavel Stehule <pavel.steh...@gmail.com>
>> wrote:
>>
>>>
>>>
>>> 2015-09-02 21:49 GMT+02:00 dinesh kumar <dineshkuma...@gmail.com>:
>>>
>>>> On Mon, Aug 31, 2015 at 10:08 PM, Pavel Stehule <
>>>> pavel.steh...@gmail.com> wrote:
>>>>
>>>>>
>>>>>
>>>>> 2015-09-01 6:59 GMT+02:00 Pavel Stehule <pavel.steh...@gmail.com>:
>>>>>
>>>>>>
>>>>>>
>>>>>> 2015-08-31 20:43 GMT+02:00 dinesh kumar <dineshkuma...@gmail.com>:
>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> On Sat, Aug 29, 2015 at 4:22 PM, Pavel Stehule <
>>>>>>> pavel.steh...@gmail.com> wrote:
>>>>>>>
>>>>>>>> Hi
>>>>>>>>
>>>>>>>> I am starting to work review of this patch
>>>>>>>>
>>>>>>>> 2015-07-13 9:54 GMT+02:00 dinesh kumar <dineshkuma...@gmail.com>:
>>>>>>>>
>>>>>>>>> Hi All,
>>>>>>>>>
>>>>>>>>> Greetings for the day.
>>>>>>>>>
>>>>>>>>> Would like to discuss on below feature here.
>>>>>>>>>
>>>>>>>>> Feature:
>>>>>>>>>     Having an SQL function, to write messages to log destination.
>>>>>>>>>
>>>>>>>>> Justification:
>>>>>>>>>     As of now, we don't have an SQL function to write
>>>>>>>>> custom/application messages to log destination. We have "RAISE" clause
>>>>>>>>> which is controlled by
>>>>>>>>> log_ parameters. If we have an SQL function which works
>>>>>>>>> irrespective of log settings, that would be a good for many log 
>>>>>>>>> parsers.
>>>>>>>>> What i mean is, in DBA point of view, if we route all our native OS 
>>>>>>>>> stats
>>>>>>>>> to log files in a proper format, then we can have our log reporting 
>>>>>>>>> tools
>>>>>>>>> to give most effective reports. Also, Applications can log their own
>>>>>>>>> messages to postgres log files, which can be monitored by DBAs too.
>>>>>>>>>
>>>>>>>>> Implementation:
>>>>>>>>>     Implemented a new function "pg_report_log" which takes one
>>>>>>>>> argument as text, and returns void. I took, "LOG" prefix for all the
>>>>>>>>> reporting messages.I wasn't sure to go with new prefix for this, since
>>>>>>>>> these are normal LOG messages. Let me know, if i am wrong here.
>>>>>>>>>
>>>>>>>>> Here is the attached patch.
>>>>>>>>>
>>>>>>>>
>>>>>>>> This patch is not complex, but the implementation doesn't cover a
>>>>>>>> "ereport" well.
>>>>>>>>
>>>>>>>> Although this functionality should be replaced by custom function
>>>>>>>> in any PL (now or near future), I am not against to have this function 
>>>>>>>> in
>>>>>>>> core. There are lot of companies with strong resistance against stored
>>>>>>>> procedures - and sometimes this functionality can help with SQL 
>>>>>>>> debugging.
>>>>>>>>
>>>>>>>> Issues:
>>>>>>>>
>>>>>>>> 1. Support only MESSAGE field in exception - I am expecting to
>>>>>>>> support all fields: HINT, DETAIL, ...
>>>>>>>>
>>>>>>>
>>>>>>> Added these functionalities too.
>>>>>>>
>>>>>>>
>>>>>>>> 2. Missing regress tests
>>>>>>>>
>>>>>>>
>>>>>>> Adding here.
>>>>>>>
>>>>>>>
>>>>>>>> 3. the parsing ereport level should be public function shared with
>>>>>>>> PLpgSQL and other PL
>>>>>>>>
>>>>>>>
>>>>>>> Sorry Pavel. I am not getting your point here. Would you give me an
>>>>>>> example.
>>>>>>>
>>>>>>
>>>>>> The transformation: text -> error level is common task - and PLpgSQL
>>>>>> it does in pl_gram.y. My idea is to add new function to error utils named
>>>>>> "parse_error_level" and use it from PLpgSQL and from your code.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> 4. should be hidestmt mandatory parameter?
>>>>>>>>
>>>>>>>
>>>>>>> I changed this argument's default value as "true".
>>>>>>>
>>>>>>>
>>>>>>>> 5. the function declaration is strange
>>>>>>>>
>>>>>>>> postgres=# \sf pg_report_log (text, anyelement, boolean)
>>>>>>>> CREATE OR REPLACE FUNCTION pg_catalog.pg_report_log(text,
>>>>>>>> anyelement, boolean)
>>>>>>>>  RETURNS void
>>>>>>>>  LANGUAGE sql
>>>>>>>>  STABLE STRICT COST 1
>>>>>>>> AS $function$SELECT pg_report_log($1::pg_catalog.text,
>>>>>>>> $2::pg_catalog.text, $3::boolean)$function$
>>>>>>>>
>>>>>>>> Why polymorphic? It is useless on any modern release
>>>>>>>>
>>>>>>>>
>>>>>>> I took quote_ident(anyelement) as referral code, for implementing
>>>>>>> this. Could you guide me if I am doing wrong here.
>>>>>>>
>>>>>>
>>>>>> I was wrong - this is ok - it is emulation of force casting to text
>>>>>>
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> postgres=# \sf pg_report_log (text, text, boolean)
>>>>>>>> CREATE OR REPLACE FUNCTION pg_catalog.pg_report_log(text, text,
>>>>>>>> boolean)
>>>>>>>>  RETURNS void
>>>>>>>>  LANGUAGE internal
>>>>>>>>  IMMUTABLE STRICT
>>>>>>>> AS $function$pg_report_log$function$
>>>>>>>>
>>>>>>>> Why stable, why immutable? This function should be volatile.
>>>>>>>>
>>>>>>>> Fixed these to volatile.
>>>>>>>
>>>>>>>
>>>>>>>> 6. using elog level enum as errcode is wrong idea - errcodes are
>>>>>>>> defined in table
>>>>>>>> http://www.postgresql.org/docs/9.4/static/errcodes-appendix.html
>>>>>>>>
>>>>>>>
>>>>>>> You mean, if the elevel is 'ERROR', then we need to allow errcode.
>>>>>>> Let me know your inputs.
>>>>>>>
>>>>>>
>>>>>> I was blind, but the code was not good. Yes, error and higher needs
>>>>>> error code. From ANSI/SQL anything can has error code "00 is ok", "01 ..
>>>>>> warnings" ...
>>>>>>
>>>>>> There is more possibilities - look to PLpgSQL implementation - it can
>>>>>> be optional parameter - it default can use ERRCODE_RAISE_EXCEPTION
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Adding new patch, with the above fixes.
>>>>>>>
>>>>>>
>>>>> the code looks better
>>>>>
>>>>> my objections:
>>>>>
>>>>> 1. I prefer default values be NULL
>>>>>
>>>>
>>>> Fixed it.
>>>>
>>>>
>>>>> 2. readability:
>>>>>   * parsing error level should be in alone cycle
>>>>>   * you don't need to use more ereport calls - one is good enough -
>>>>> look on implementation of stmt_raise in PLpgSQL
>>>>>
>>>>
>>>> Sorry for my ignorance. I have tried to implement parse_error_level in
>>>> pl_gram.y, but not able to do it. I was not able to parse the given string
>>>> with tokens, and return the error levels. I tried for a refferal code, but
>>>> not able to find any. Would you guide me on this.
>>>>
>>>> In this attached patch, I have minimized the ereport calls. Kindly
>>>> check and let me know.
>>>>
>>>>
>>>>> 3. test should be enhanced for optional parameters
>>>>>
>>>>> Fixed it.
>>>>
>>>
>>> only few points:
>>>
>>> 1. missing to set errstate - any exception should to have some errcode
>>> value. There can be default like PLpgSQL ERRCODE_RAISE_EXCEPTION for any
>>> where elog_level >= error
>>>
>>>
>> Fixed It.
>>
>
> it should be a optional parameter,
>
> please fix doc, there are not any difference between mandatory and
> optional parametere
>
>>
>>
>
Fixed this.


> 2. the explicit setting context is not consistent with our PL - the
>>> context is implicit value only - not possible to set it explicitly. The
>>> behave of this field is not clear - but in this moment, the context is
>>> related to PostgreSQL area - not to application area.
>>>
>>
>> OK. Shall i remove the context field from this function.
>>
>
> ok
>
>
Fixed this.

Thanks much.


>
>> Regards,
>> Dinesh
>> manojadinesh.blogspot.com
>>
>> Regards
>>>
>>> Pavel
>>>
>>>
>>>> Regards,
>>>> Dinesh
>>>> manojadinesh.blogspot.com
>>>>
>>>> Regards
>>>>>
>>>>> Pavel
>>>>>
>>>>>
>>>>>>
>>>>>>> Thanks in advance.
>>>>>>>
>>>>>>> Regards,
>>>>>>> Dinesh
>>>>>>>
>>>>>>>>
>>>>>>>> Regards
>>>>>>>>
>>>>>>>> Pavel
>>>>>>>>
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Regards,
>>>>>>>>> Dinesh
>>>>>>>>> manojadinesh.blogspot.com
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>


-- 

Regards,
Dinesh
manojadinesh.blogspot.com
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index b3b78d2..682164e 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -17925,6 +17925,15 @@ postgres=# SELECT * FROM 
pg_xlogfile_name_offset(pg_stop_backup());
         Return information about a file.
        </entry>
       </row>
+      <row>
+       <entry>
+        <literal><function>pg_report_log(<parameter>elevel</><type>text</>, 
<parameter>message</> <type>anyelement</>[, <parameter>ishidestmt</> 
<type>boolean</>, <parameter>detail</> <type> text</>, <parameter>hint</> 
<type>text</>, <parameter>iserrstate</> <type>boolean</>])</function></literal>
+       </entry>
+       <entry><type>void</type></entry>
+       <entry>
+        Write message to log destination.
+       </entry>
+      </row>
      </tbody>
     </tgroup>
    </table>
@@ -17993,6 +18002,25 @@ SELECT (pg_stat_file('filename')).modification;
 </programlisting>
    </para>
 
+   <indexterm>
+    <primary>pg_report_log</primary>
+   </indexterm>
+   <para>
+    <function>pg_report_log</> is useful to write custom messages
+    into current log destination and returns <type>void</type>.
+    This function don't support the PANIC, FATAL log levels due to their 
unique internal DB usage, which may cause the database instability. Using 
<parameter>ishidestmt</> which default values is true, function can write or 
ignore the current SQL statement into log destination. Also, we can have 
DETAIL, HINT log messages by provding <parameter>detail</>, <parameter>hint</> 
as function arguments, which are NULL by default. Using 
<parameter>iserrstate</> which default values is true, enables the function to 
raise the SQLSTATE as ERRCODE_RAISE_EXCEPTION for the only ERROR level.
+
+    Typical usages include:
+<programlisting>
+postgres=# SELECT pg_report_log('NOTICE', 'Custom Message', true);
+NOTICE:  Custom Message
+ pg_report_log 
+---------------
+ 
+(1 row)
+</programlisting>
+   </para>
+
   </sect2>
 
   <sect2 id="functions-advisory-locks">
diff --git a/src/backend/catalog/system_views.sql 
b/src/backend/catalog/system_views.sql
index ccc030f..f1ddc35 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -940,3 +940,18 @@ RETURNS jsonb
 LANGUAGE INTERNAL
 STRICT IMMUTABLE
 AS 'jsonb_set';
+
+CREATE OR REPLACE FUNCTION pg_report_log(elevel TEXT, message TEXT, ishidestmt 
BOOLEAN DEFAULT TRUE, detail TEXT DEFAULT NULL, hint TEXT DEFAULT NULL, 
iserrstate BOOLEAN DEFAULT TRUE)
+RETURNS VOID
+LANGUAGE INTERNAL
+VOLATILE
+AS 'pg_report_log';
+
+CREATE OR REPLACE FUNCTION pg_report_log(elevel TEXT, message anyelement, 
ishidestmt BOOLEAN DEFAULT TRUE, detail TEXT DEFAULT NULL, hint TEXT DEFAULT 
NULL, iserrstate BOOLEAN DEFAULT TRUE)
+RETURNS VOID
+VOLATILE
+AS
+$$
+SELECT pg_report_log($1::pg_catalog.text, $2::pg_catalog.text, 
$3::pg_catalog.bool, $4::pg_catalog.text, $5::pg_catalog.text, 
$6::pg_catalog.bool)
+$$
+LANGUAGE SQL;
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index c0495d9..d2f10c9 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -75,6 +75,98 @@ current_query(PG_FUNCTION_ARGS)
                PG_RETURN_NULL();
 }
 
+
+/*
+ * Parsing error levels
+ */
+typedef struct
+{
+       int ecode;
+       char *level;
+} errorlevels;
+
+static int parse_error_level(const char* elevel)
+{
+       errorlevels elevels[]={
+                       {DEBUG5, "DEBUG5"}, {DEBUG4, "DEBUG4"}, {DEBUG3, 
"DEBUG3"},
+                       {DEBUG2, "DEBUG2"}, {DEBUG1, "DEBUG1"}, {LOG, "LOG"},
+                       {COMMERROR, "COMMERROR"}, {INFO, "INFO"}, {NOTICE, 
"NOTICE"},
+                       {WARNING, "WARNING"}, {ERROR, "ERROR"}, {FATAL, 
"FATAL"}, {PANIC, "PANIC"}
+                       /*
+                        * Adding PGERROR to elevels if WIN32
+                        */
+                       #ifdef WIN32
+                       ,{PGERROR, "PGERROR"}
+                       #endif
+       };
+       int noelevel = (int) sizeof(elevels)/sizeof(*elevels);
+       int itr = 0;
+
+       while (itr < noelevel)
+       {
+               if (pg_strcasecmp(elevels[itr].level, elevel) == 0)
+                       break;
+               itr++;
+       }
+
+       if (itr != noelevel)
+               return elevels[itr].ecode;
+       /* Invalid log level */
+       else
+               return 0;
+}
+
+/*
+ * pg_report_log()
+ *
+ * Printing custom log messages in log file.
+ */
+
+Datum
+pg_report_log(PG_FUNCTION_ARGS)
+{
+       int elevel;
+       bool ishidestmt = false, iserrstate = false;
+       char *loglevel, *detail, *hint;
+
+       loglevel        = PG_ARGISNULL(0) ? NULL : 
text_to_cstring(PG_GETARG_TEXT_P(0));
+       ishidestmt      = PG_ARGISNULL(2) ? false :     PG_GETARG_BOOL(2);
+       detail          = PG_ARGISNULL(3) ? NULL : 
text_to_cstring(PG_GETARG_TEXT_P(3));
+       hint            = PG_ARGISNULL(4) ? NULL : 
text_to_cstring(PG_GETARG_TEXT_P(4));
+       iserrstate      = PG_ARGISNULL(5) ? false : PG_GETARG_BOOL(5);
+
+       if(!loglevel)
+               ereport(ERROR,
+                               (errmsg("NULL is an unsupported report log 
level.")));
+
+       elevel = parse_error_level(loglevel);
+
+       /*
+        * Do not expose FATAL, PANIC log levels to outer world.
+        */
+       if(elevel && elevel==FATAL)
+               ereport(ERROR,
+                               (errmsg("%s is an unsupported report log 
level.", loglevel)));
+
+       else if(elevel && elevel==PANIC)
+               ereport(ERROR,
+                               (errmsg("%s is an unsupported report log 
level.", loglevel)));
+
+       else if(elevel)
+               ereport(elevel,
+                               ( ((elevel>=ERROR) && iserrstate ) ? 
errcode(ERRCODE_RAISE_EXCEPTION) : 0,
+                               (errmsg("%s", PG_ARGISNULL(1) ? "" : 
text_to_cstring(PG_GETARG_TEXT_P(1))),
+                                               detail ? errdetail("%s", 
detail) : 0,
+                                               hint ? errhint("%s", hint) : 0,
+                                               errhidestmt(ishidestmt)
+                               )));
+       else
+               ereport(ERROR,
+                               (errmsg("%s is an unknown report log level.", 
loglevel)));
+
+                       PG_RETURN_VOID();
+}
+
 /*
  * Send a signal to another backend.
  *
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index ddf7c67..0474b2a 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -5349,6 +5349,13 @@ DESCR("row security for current context active on table 
by table oid");
 DATA(insert OID = 3299 (  row_security_active     PGNSP PGUID 12 1 0 0 0 f f f 
f t f s 1 0 16 "25" _null_ _null_ _null_ _null_ _null_  
row_security_active_name _null_ _null_ _null_ ));
 DESCR("row security for current context active on table by table name");
 
+/* Logging function */
+
+DATA(insert OID = 6015 (  pg_report_log                PGNSP PGUID 12 1 0 0 0 
f f f f f f v 6 0 2278 "25 25 16 25 25 16" _null_ _null_ "{elevel, message, 
ishidestmt, detail, hint, iserrstate}" _null_ _null_ pg_report_log _null_ 
_null_ _null_ ));
+DESCR("write message to log file");
+DATA(insert OID = 6016 (  pg_report_log                PGNSP PGUID 14 1 0 0 0 
f f f f f f v 6 0 2278 "25 2283 16 25 25 16" _null_ _null_ "{elevel, message, 
ishidestmt, detail, hint, iserrstate}" _null_ _null_ "SELECT 
pg_report_log($1::pg_catalog.text, $2::pg_catalog.text, $3::pg_catalog.bool, 
$4::pg_catalog.text, $5::pg_catalog.text, $6::pg_catalog.bool)" _null_ _null_ 
_null_ ));
+DESCR("write message to log file");
+
 /*
  * Symbolic values for proargmodes column.  Note that these must agree with
  * the FunctionParameterMode enum in parsenodes.h; we declare them here to
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index fc1679e..0dd1425 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -495,6 +495,7 @@ extern Datum pg_typeof(PG_FUNCTION_ARGS);
 extern Datum pg_collation_for(PG_FUNCTION_ARGS);
 extern Datum pg_relation_is_updatable(PG_FUNCTION_ARGS);
 extern Datum pg_column_is_updatable(PG_FUNCTION_ARGS);
+extern Datum pg_report_log(PG_FUNCTION_ARGS);
 
 /* oid.c */
 extern Datum oidin(PG_FUNCTION_ARGS);
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 7684717..4ec2eb1 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -16,6 +16,13 @@
 
 #include <setjmp.h>
 
+/*
+ * XXX
+ *             If you are adding another elevel, make sure you update the
+ *             parse_error_level() in src/backend/utils/adt/misc.c, with the
+ *             new elevel
+ */
+
 /* Error level codes */
 #define DEBUG5         10                      /* Debugging messages, in 
categories of
                                                                 * decreasing 
detail. */
diff --git a/src/test/regress/expected/reportlog.out 
b/src/test/regress/expected/reportlog.out
new file mode 100644
index 0000000..8811c12
--- /dev/null
+++ b/src/test/regress/expected/reportlog.out
@@ -0,0 +1,88 @@
+--
+-- Test for Report Log With WARNING
+--
+SELECT pg_catalog.pg_report_log('WARNING', 'Custom Message'); --OK
+WARNING:  Custom Message
+ pg_report_log 
+---------------
+ 
+(1 row)
+
+--
+-- Test for ERROR with default ishidestmt
+--
+SELECT pg_catalog.pg_report_log('ERROR', 'Custom Message'); --ERROR
+ERROR:  Custom Message
+--
+-- Test for ERROR with ishidestmt
+--
+SELECT pg_catalog.pg_report_log('ERROR', 'Custom Message', true); --ERROR
+ERROR:  Custom Message
+--
+-- Test for anyelement
+--
+SELECT pg_catalog.pg_report_log('WARNING', -1234.34); --OK
+WARNING:  -1234.34
+ pg_report_log 
+---------------
+ 
+(1 row)
+
+--
+-- Test for denial of FATAL
+--
+SELECT pg_catalog.pg_report_log('FATAL', 'Fatal Message'); --OK
+ERROR:  FATAL is an unsupported report log level.
+--
+-- Test for optional arguements
+--
+SELECT pg_catalog.pg_report_log('WARNING', 'Warning Message', true, 'WARNING 
DETAIL'); --OK
+WARNING:  Warning Message
+DETAIL:  WARNING DETAIL
+ pg_report_log 
+---------------
+ 
+(1 row)
+
+--
+-- Test for NULL elevel
+--
+SELECT pg_catalog.pg_report_log(NULL, NULL); --ERROR
+ERROR:  NULL is an unsupported report log level.
+--
+-- Test for NULL Message
+--
+SELECT pg_catalog.pg_report_log('NOTICE', NULL); --OK
+NOTICE:  
+ pg_report_log 
+---------------
+ 
+(1 row)
+
+--
+-- Test for iserrstate. The below test should print P0001, which is an error 
code for ERRCODE_RAISE_EXCEPTION
+--
+DO $$ BEGIN PERFORM pg_catalog.pg_report_log('ERROR', NULL, NULL, NULL, NULL, 
true); EXCEPTION WHEN OTHERS THEN RAISE NOTICE '%', SQLSTATE; END $$;
+NOTICE:  P0001
+--
+-- Test for all NULL inputs, except elevel
+--
+SELECT pg_catalog.pg_report_log('WARNING', NULL, NULL, NULL, NULL, NULL); --OK
+WARNING:  
+ pg_report_log 
+---------------
+ 
+(1 row)
+
+--
+-- Test for all NOT NULL arguments
+--
+SELECT pg_catalog.pg_report_log('WARNING', 'Warning Message', true, 'DETAIL', 
'HINT', true); --OK
+WARNING:  Warning Message
+DETAIL:  DETAIL
+HINT:  HINT
+ pg_report_log 
+---------------
+ 
+(1 row)
+
diff --git a/src/test/regress/parallel_schedule 
b/src/test/regress/parallel_schedule
index 6fc5d1e..4cd193d 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -97,7 +97,7 @@ test: rules
 # ----------
 # Another group of parallel tests
 # ----------
-test: select_views portals_p2 foreign_key cluster dependency guc bitmapops 
combocid tsearch tsdicts foreign_data window xmlmap functional_deps 
advisory_lock json jsonb indirect_toast equivclass
+test: select_views portals_p2 foreign_key cluster dependency guc bitmapops 
combocid tsearch tsdicts foreign_data window xmlmap functional_deps 
advisory_lock json jsonb indirect_toast reportlog equivclass
 # ----------
 # Another group of parallel tests
 # NB: temp.sql does a reconnect which transiently uses 2 connections,
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 2ae51cf..6c9f5c3 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -158,3 +158,4 @@ test: with
 test: xml
 test: event_trigger
 test: stats
+test: reportlog
diff --git a/src/test/regress/sql/reportlog.sql 
b/src/test/regress/sql/reportlog.sql
new file mode 100644
index 0000000..a838fc7
--- /dev/null
+++ b/src/test/regress/sql/reportlog.sql
@@ -0,0 +1,55 @@
+--
+-- Test for Report Log With WARNING
+--
+SELECT pg_catalog.pg_report_log('WARNING', 'Custom Message'); --OK
+
+--
+-- Test for ERROR with default ishidestmt
+--
+SELECT pg_catalog.pg_report_log('ERROR', 'Custom Message'); --ERROR
+
+--
+-- Test for ERROR with ishidestmt
+--
+SELECT pg_catalog.pg_report_log('ERROR', 'Custom Message', true); --ERROR
+
+--
+-- Test for anyelement
+--
+SELECT pg_catalog.pg_report_log('WARNING', -1234.34); --OK
+
+--
+-- Test for denial of FATAL
+--
+SELECT pg_catalog.pg_report_log('FATAL', 'Fatal Message'); --OK
+
+--
+-- Test for optional arguements
+--
+SELECT pg_catalog.pg_report_log('WARNING', 'Warning Message', true, 'WARNING 
DETAIL'); --OK
+
+--
+-- Test for NULL elevel
+--
+SELECT pg_catalog.pg_report_log(NULL, NULL); --ERROR
+
+
+--
+-- Test for NULL Message
+--
+SELECT pg_catalog.pg_report_log('NOTICE', NULL); --OK
+
+--
+-- Test for iserrstate. The below test should print P0001, which is an error 
code for ERRCODE_RAISE_EXCEPTION
+--
+DO $$ BEGIN PERFORM pg_catalog.pg_report_log('ERROR', NULL, NULL, NULL, NULL, 
true); EXCEPTION WHEN OTHERS THEN RAISE NOTICE '%', SQLSTATE; END $$;
+
+--
+-- Test for all NULL inputs, except elevel
+--
+SELECT pg_catalog.pg_report_log('WARNING', NULL, NULL, NULL, NULL, NULL); --OK
+
+--
+-- Test for all NOT NULL arguments
+--
+SELECT pg_catalog.pg_report_log('WARNING', 'Warning Message', true, 'DETAIL', 
'HINT', true); --OK
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to