1 /*-------------------------------------------------------------------------
2  *
3  * cmdtag.c
4  *	  Data and routines for commandtag names and enumeration.
5  *
6  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  *	  src/backend/tcop/cmdtag.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15 
16 #include "miscadmin.h"
17 #include "tcop/cmdtag.h"
18 
19 
20 typedef struct CommandTagBehavior
21 {
22 	const char *name;
23 	const bool	event_trigger_ok;
24 	const bool	table_rewrite_ok;
25 	const bool	display_rowcount;
26 } CommandTagBehavior;
27 
28 #define PG_CMDTAG(tag, name, evtrgok, rwrok, rowcnt) \
29 	{ name, evtrgok, rwrok, rowcnt },
30 
31 const CommandTagBehavior tag_behavior[COMMAND_TAG_NEXTTAG] = {
32 #include "tcop/cmdtaglist.h"
33 };
34 
35 #undef PG_CMDTAG
36 
37 void
InitializeQueryCompletion(QueryCompletion * qc)38 InitializeQueryCompletion(QueryCompletion *qc)
39 {
40 	qc->commandTag = CMDTAG_UNKNOWN;
41 	qc->nprocessed = 0;
42 }
43 
44 const char *
GetCommandTagName(CommandTag commandTag)45 GetCommandTagName(CommandTag commandTag)
46 {
47 	return tag_behavior[commandTag].name;
48 }
49 
50 bool
command_tag_display_rowcount(CommandTag commandTag)51 command_tag_display_rowcount(CommandTag commandTag)
52 {
53 	return tag_behavior[commandTag].display_rowcount;
54 }
55 
56 bool
command_tag_event_trigger_ok(CommandTag commandTag)57 command_tag_event_trigger_ok(CommandTag commandTag)
58 {
59 	return tag_behavior[commandTag].event_trigger_ok;
60 }
61 
62 bool
command_tag_table_rewrite_ok(CommandTag commandTag)63 command_tag_table_rewrite_ok(CommandTag commandTag)
64 {
65 	return tag_behavior[commandTag].table_rewrite_ok;
66 }
67 
68 /*
69  * Search CommandTag by name
70  *
71  * Returns CommandTag, or CMDTAG_UNKNOWN if not recognized
72  */
73 CommandTag
GetCommandTagEnum(const char * commandname)74 GetCommandTagEnum(const char *commandname)
75 {
76 	const CommandTagBehavior *base,
77 			   *last,
78 			   *position;
79 	int			result;
80 
81 	if (commandname == NULL || *commandname == '\0')
82 		return CMDTAG_UNKNOWN;
83 
84 	base = tag_behavior;
85 	last = tag_behavior + lengthof(tag_behavior) - 1;
86 	while (last >= base)
87 	{
88 		position = base + ((last - base) >> 1);
89 		result = pg_strcasecmp(commandname, position->name);
90 		if (result == 0)
91 			return (CommandTag) (position - tag_behavior);
92 		else if (result < 0)
93 			last = position - 1;
94 		else
95 			base = position + 1;
96 	}
97 	return CMDTAG_UNKNOWN;
98 }
99