You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafodion.apache.org by db...@apache.org on 2019/02/12 17:43:39 UTC
[trafodion] branch master updated: [TRAFODION-3261] Change logsort
tool to sort GET statement output also
This is an automated email from the ASF dual-hosted git repository.
dbirdsall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafodion.git
The following commit(s) were added to refs/heads/master by this push:
new 5aa3806 [TRAFODION-3261] Change logsort tool to sort GET statement output also
new bae8752 Merge pull request #1793 from DaveBirdsall/Trafodion3261
5aa3806 is described below
commit 5aa3806f2fbbe90163e2844698a1c372f64e0f31
Author: Dave Birdsall <db...@apache.org>
AuthorDate: Mon Feb 11 20:08:33 2019 +0000
[TRAFODION-3261] Change logsort tool to sort GET statement output also
---
core/sql/regress/tools/logsort_src/line.c | 35 ++++++++
core/sql/regress/tools/logsort_src/line.h | 2 +
core/sql/regress/tools/logsort_src/logsort.c | 128 +++++++++++++++++++++++++++
core/sql/regress/tools/logsort_src/tokstr.c | 86 ++++++++++++++++--
core/sql/regress/tools/logsort_src/tokstr.h | 5 +-
5 files changed, 248 insertions(+), 8 deletions(-)
diff --git a/core/sql/regress/tools/logsort_src/line.c b/core/sql/regress/tools/logsort_src/line.c
index 057db9a..6ceab36 100755
--- a/core/sql/regress/tools/logsort_src/line.c
+++ b/core/sql/regress/tools/logsort_src/line.c
@@ -561,3 +561,38 @@ else
return rc;
}
+
+/*
+
+ line_isgetheadingorfooting
+
+ This function determines if a line is a header or footer line
+ for GET statement output.
+
+ entry parameters: line - the line to analyze
+
+ exit parameters: returns TRUE if so, FALSE if not.
+
+ */
+
+int line_isgetheadingorfooting(char *line)
+{
+return (strncmp(line,"==========",10) == 0);
+}
+
+/*
+
+ line_issqloperationcomplete
+
+ This function determines if a line is "SQL operation complete."
+
+ entry parameters: line - the line to analyze
+
+ exit parameters: returns TRUE if so, FALSE if not.
+
+ */
+
+int line_issqloperationcomplete(char *line)
+{
+return (strcmp(line,"--- SQL operation complete.\n") == 0);
+}
diff --git a/core/sql/regress/tools/logsort_src/line.h b/core/sql/regress/tools/logsort_src/line.h
index 84bfbcc..a2a9fc2 100755
--- a/core/sql/regress/tools/logsort_src/line.h
+++ b/core/sql/regress/tools/logsort_src/line.h
@@ -40,3 +40,5 @@ int line_isnnrows(char *line);
int line_isignore(char *line);
int line_isstats(char *line);
int line_isoptstats(char *line);
+int line_isgetheadingorfooting(char *line);
+int line_issqloperationcomplete(char *line);
diff --git a/core/sql/regress/tools/logsort_src/logsort.c b/core/sql/regress/tools/logsort_src/logsort.c
index 29af62d..69074a1 100755
--- a/core/sql/regress/tools/logsort_src/logsort.c
+++ b/core/sql/regress/tools/logsort_src/logsort.c
@@ -496,6 +496,21 @@ else
}
token_stream_advance(t,1); /* advance past SELECT */
}
+ else if (token_stream_is_get(t))
+ {
+ /* we are just after a GET with sortable output */
+ headingcount = 0;
+ if (line_isblank(linebuf)) state = 10;
+ else if (line_is0rows(linebuf)) state = 0;
+ else if (line_iserror(linebuf)) state = 0;
+ else
+ {
+ printf("Unexpected line after a GET statement:\n");
+ printf("%s",linebuf);
+ state = 0;
+ }
+ token_stream_advance(t,1); /* advance past GET */
+ }
else
{
/* We are just after some other statement. If the
@@ -691,6 +706,119 @@ else
myFputs(linebuf,out,strip_stats_option,mightbestats(state));
break;
}
+ case 10: /* after blank line after GET statement */
+ {
+ if (line_isheading(linebuf)) state = 11;
+ /* 0 rows selected after a blank line can happen with Trafodion sqlci */
+ else if (line_issqloperationcomplete(linebuf))
+ state = 0; /* for Trafodion */
+ /* error message after a blank line can happen with Trafodion sqlci */
+ else if (line_iserror(linebuf))
+ state = 0; /* for Trafodion */
+ /* warning messages occur after a blank line also in Trafodion sqlci */
+ else if (line_iswarning(linebuf))
+ state = 9; /* there will be a blank line after the warning */
+ else
+ {
+ printf("Unexpected line after a GET statement:\n");
+ printf("%s",linebuf);
+ state = 0;
+ }
+ myFputs(linebuf,out,strip_stats_option,mightbestats(state));
+ break;
+ }
+ case 11: /* after GET statement header text, e.g. "Tables in Schema TRAFODION.SCH" */
+ {
+ if (line_isgetheadingorfooting(linebuf))
+ {
+ headingcount++;
+ state = 12;
+ }
+ /* 0 rows selected after a blank line can happen with Trafodion sqlci */
+ else if (line_is0rows(linebuf))
+ state = 0; /* for Trafodion */
+ /* error message after a blank line can happen with Trafodion sqlci */
+ else if (line_iserror(linebuf))
+ state = 0; /* for Trafodion */
+ /* warning messages occur after a blank line also in Trafodion sqlci */
+ else if (line_iswarning(linebuf))
+ state = 9; /* there will be a blank line after the warning */
+ else
+ {
+ printf("Unexpected line after a GET statement:\n");
+ printf("%s",linebuf);
+ state = 0;
+ }
+ myFputs(linebuf,out,strip_stats_option,mightbestats(state));
+ break;
+ }
+ case 12: /* after "===============" header line for GET statement */
+ {
+ if (line_isblank(linebuf))
+ {
+ state = 13;
+ line_within_row = 0;
+ }
+ else
+ {
+ printf("Unexpected line after a GET header:\n");
+ printf("%s",linebuf);
+ state = 0;
+ }
+ myFputs(linebuf,out,strip_stats_option,mightbestats(state));
+ break;
+ }
+ case 13: /* we are at a row of GET statement output */
+ {
+ if (line_isblank(linebuf))
+ {
+ /* a blank line means no more GET output */
+
+ if (rw) /* add any outstanding row to the list */
+ {
+ row_list_add(r,rw);
+ rw = NULL;
+ }
+
+ struct row *rw1;
+ char *returned_line;
+
+ while ((rw1 = row_list_remove_min(r)) != NULL)
+ {
+ while ((returned_line = row_remove(rw1)) != NULL)
+ {
+ myFputs(returned_line,out,strip_stats_option,mightbestats(state));
+ }
+ row_destroy(rw1);
+ }
+
+ myFputs(linebuf,out,strip_stats_option,mightbestats(state));
+
+ /* BUG - the test in the next statement should be:
+ if (there are outstanding statements) ...
+ But, need to write a new token_stream fn. to do this */
+
+ if (token_stream_interesting(t)) state = 2;
+ else if (token_stream_is_get(t)) state = 2;
+ else state = 0;
+ }
+ else
+ {
+ if (line_within_row == headingcount)
+ {
+ row_list_add(r,rw);
+ rw = NULL;
+ line_within_row = 0;
+ }
+ if (line_within_row == 0)
+ {
+ rw = row_create(headingcount);
+ }
+ row_add(rw,linebuf);
+ line_within_row++;
+ }
+ break;
+ }
default:
{
printf("Error: got bad state %d.\n",state);
diff --git a/core/sql/regress/tools/logsort_src/tokstr.c b/core/sql/regress/tools/logsort_src/tokstr.c
index 8703ffa..f0603d5 100755
--- a/core/sql/regress/tools/logsort_src/tokstr.c
+++ b/core/sql/regress/tools/logsort_src/tokstr.c
@@ -56,7 +56,10 @@
#define TOKEN_MXCI_DIRECTIVE 10 /* a SQL/MX MXCI directive */
-#define TOKEN_OTHER 11
+#define TOKEN_GET 11
+#define TOKEN_OBJECT_TYPE 12
+
+#define TOKEN_OTHER 13
/* parse states */
@@ -79,6 +82,10 @@
#define START_AFTER_NULL_STMT 13
+#define IN_GET 14
+#define IN_INTERESTING_GET 15
+#define FOUND_INTERESTING_GET 16
+
/*
token_stream_create
@@ -150,6 +157,7 @@ switch (state)
else if (token_type == TOKEN_PREPARE) rc = IN_PREPARE;
else if (token_type == TOKEN_EXECUTE) rc = IN_EXECUTE;
else if (token_type == TOKEN_MXCI_DIRECTIVE) rc = START; /* so we ignore directives */
+ else if (token_type == TOKEN_GET) rc = IN_GET;
else if (token_type != TOKEN_SEMICOLON) rc = IN_OTHER;
else rc = START_AFTER_NULL_STMT;
break;
@@ -170,9 +178,11 @@ switch (state)
else rc = IN_SELECT;
break;
}
+ case FOUND_INTERESTING_GET:
case FOUND_SELECT_WITHOUT_ORDER_BY:
{
if (token_type == TOKEN_SELECT) rc = IN_SELECT;
+ else if (token_type == TOKEN_GET) rc = IN_GET;
else if (token_type == TOKEN_PREPARE) rc = IN_PREPARE;
else if (token_type == TOKEN_EXECUTE) rc = IN_EXECUTE;
else if (token_type == TOKEN_MXCI_DIRECTIVE) rc = START; /* so we ignore MXCI directives */
@@ -281,6 +291,19 @@ switch (state)
else if (token_type != TOKEN_SEMICOLON) rc = IN_OTHER;
break;
}
+ case IN_GET:
+ {
+ if (token_type == TOKEN_OBJECT_TYPE) rc = IN_INTERESTING_GET;
+ else if (token_type == TOKEN_SEMICOLON) rc = START;
+ /* else remain in IN_GET state */
+ break;
+ }
+ case IN_INTERESTING_GET:
+ {
+ if (token_type == TOKEN_SEMICOLON) rc = FOUND_INTERESTING_GET;
+ /* else remain in IN_INTERESTING_GET state */
+ break;
+ }
default:
{
printf("Error: unknown token type %d.\n",token_type);
@@ -322,7 +345,7 @@ else if (isalpha(*token))
{
int length;
int i;
- char buffer[10];
+ char buffer[20];
*token_type_ptr = TOKEN_IDENTIFIER;
@@ -330,7 +353,7 @@ else if (isalpha(*token))
isdigit(*next) ||
(*next == '_'); next++) ;
length = next - token;
- if (length < 10)
+ if (length < 20)
{
for (i = 0; i < length; i++) buffer[i] = toupper(token[i]);
buffer[i] = '\0';
@@ -346,6 +369,18 @@ else if (isalpha(*token))
else if (strcmp(buffer,"PREPARE") == 0) *token_type_ptr = TOKEN_PREPARE;
else if (strcmp(buffer,"FROM") == 0) *token_type_ptr = TOKEN_FROM;
else if (strcmp(buffer,"EXECUTE") == 0) *token_type_ptr = TOKEN_EXECUTE;
+ else if (strcmp(buffer,"GET") == 0) *token_type_ptr = TOKEN_GET;
+ else if (strcmp(buffer,"TABLES") == 0) *token_type_ptr = TOKEN_OBJECT_TYPE; /* for GET statement */
+ else if (strcmp(buffer,"INDEXES") == 0) *token_type_ptr = TOKEN_OBJECT_TYPE; /* for GET statement */
+ else if (strcmp(buffer,"LIBRARIES") == 0) *token_type_ptr = TOKEN_OBJECT_TYPE; /* for GET statement */
+ else if (strcmp(buffer,"SCHEMAS") == 0) *token_type_ptr = TOKEN_OBJECT_TYPE; /* for GET statement */
+ else if (strcmp(buffer,"VIEWS") == 0) *token_type_ptr = TOKEN_OBJECT_TYPE; /* for GET statement */
+ else if (strcmp(buffer,"PRIVILEGES") == 0) *token_type_ptr = TOKEN_OBJECT_TYPE; /* for GET statement */
+ else if (strcmp(buffer,"FUNCTIONS") == 0) *token_type_ptr = TOKEN_OBJECT_TYPE; /* for GET statement */
+ else if (strcmp(buffer,"PROCEDURES") == 0) *token_type_ptr = TOKEN_OBJECT_TYPE; /* for GET statement */
+ else if (strcmp(buffer,"SEQUENCES") == 0) *token_type_ptr = TOKEN_OBJECT_TYPE; /* for GET statement */
+ else if (strcmp(buffer,"ROLES") == 0) *token_type_ptr = TOKEN_OBJECT_TYPE; /* for GET statement */
+ else if (strcmp(buffer,"OBJECTS") == 0) *token_type_ptr = TOKEN_OBJECT_TYPE; /* for GET statement */
}
}
else if (*token == ';')
@@ -497,13 +532,30 @@ while (*next != '\n')
while ((*next == ' ') || (*next == '\t')) next++;
if ((t->parsestate == FOUND_SELECT_WITHOUT_ORDER_BY)||
+ (t->parsestate == FOUND_INTERESTING_GET)||
(t->parsestate == START))
{
/* we have seen the end of a statement - record whether
the statement was interesting */
-
- t->stmt[t->last_stmt] =
- (t->parsestate == FOUND_SELECT_WITHOUT_ORDER_BY);
+
+ switch (t->parsestate)
+ {
+ case FOUND_SELECT_WITHOUT_ORDER_BY:
+ {
+ t->stmt[t->last_stmt] = token_stream::SELECT_WITHOUT_ORDER_BY;
+ break;
+ }
+ case FOUND_INTERESTING_GET:
+ {
+ t->stmt[t->last_stmt] = token_stream::INTERESTING_GET;
+ break;
+ }
+ default:
+ {
+ t->stmt[t->last_stmt] = token_stream::UNINTERESTING_STATEMENT;
+ break;
+ }
+ }
t->last_stmt++;
if (t->last_stmt == STMT_QUEUE_LENGTH) t->last_stmt = 0;
@@ -541,10 +593,30 @@ int token_stream_interesting(struct token_stream *t)
{
return (t->first_stmt != t->last_stmt) && /* make sure at least one stmt */
- t->stmt[t->first_stmt];
+ (t->stmt[t->first_stmt] == token_stream::SELECT_WITHOUT_ORDER_BY);
}
+/*
+
+ token_stream_is_get
+
+ This function determines whether the statement just found is
+ a GET statement with sortable output.
+
+ entry parameters: t - the token stream
+
+ exit parameter: returns TRUE if so, FALSE if not
+
+ */
+
+int token_stream_is_get(struct token_stream *t)
+
+{
+return (t->first_stmt != t->last_stmt) && /* make sure at least one stmt */
+ (t->stmt[t->first_stmt] == token_stream::INTERESTING_GET);
+}
+
/*
diff --git a/core/sql/regress/tools/logsort_src/tokstr.h b/core/sql/regress/tools/logsort_src/tokstr.h
index 40b1ee1..741d40b 100755
--- a/core/sql/regress/tools/logsort_src/tokstr.h
+++ b/core/sql/regress/tools/logsort_src/tokstr.h
@@ -51,7 +51,9 @@ struct token_stream
last_stmt */
int last_stmt; /* next slot to add a statement in the queue */
- int stmt[STMT_QUEUE_LENGTH]; /* a circular queue for statements */
+ enum stmtState { SELECT_WITHOUT_ORDER_BY, INTERESTING_GET, UNINTERESTING_STATEMENT };
+
+ stmtState stmt[STMT_QUEUE_LENGTH]; /* a circular queue for statements */
} ;
/* public function definitions */
@@ -59,5 +61,6 @@ struct token_stream
struct token_stream *token_stream_create(int ignore_order_by_option);
int token_stream_add(struct token_stream *t,char *text);
int token_stream_interesting(struct token_stream *t);
+int token_stream_is_get(struct token_stream *t);
void token_stream_clear(struct token_stream *t);
void token_stream_advance(struct token_stream *t,int advance_factor);