Changeset: c31533943a6b for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c31533943a6b
Modified Files:
        clients/mapiclient/mclient.1
        clients/mapiclient/mclient.c
Branch: default
Log Message:

mclient: allow more flexible object quoting for \d

Implemented feature request #2846.  Object names may now have arbitrary
parts quoted, which in case of schemas is often more natural.  This is
in line with psql's quoting rules for \d, which follow the SQL standard
for quoting.


diffs (110 lines):

diff --git a/clients/mapiclient/mclient.1 b/clients/mapiclient/mclient.1
--- a/clients/mapiclient/mclient.1
+++ b/clients/mapiclient/mclient.1
@@ -349,7 +349,9 @@ zero or more, and exactly one character 
 name is converted to lowercase, unless the object name is quoted by
 double quotes (\fB"\fP).  Examples of this, are e.g. \fI*.mytable\fP,
 \fItabletype*\fP or \fI"myschema.FOO"\fP.  Note that wildcard characters
-do not work in quoted objects.
+do not work in quoted objects.  Quoting follows SQL quoting rules.
+Arbitrary parts can be quoted, and two quotes following each other in a
+quoted string represent the quote itself.
 .TP
 \fB\eA\fP
 Enable auto commit mode.
diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c
--- a/clients/mapiclient/mclient.c
+++ b/clients/mapiclient/mclient.c
@@ -1914,7 +1914,8 @@ doFileByLines(Mapi mid, FILE *fp, const 
                                        char hasSchema = 0;
                                        char wantsSystem = 0; 
                                        unsigned int x = 0;
-                                       char *p;
+                                       char *p, *q;
+                                       char escaped = 0;
                                        if (mode != SQL)
                                                break;
                                        while (isascii((int) line[length - 1]) 
&&
@@ -1955,43 +1956,47 @@ doFileByLines(Mapi mid, FILE *fp, const 
                                        for ( ; *line && isascii((int) *line) 
&& isspace((int) *line); line++)
                                                ;
 
-                                       /* is the object quoted? we only 
support fully
-                                        * quoted objects, not partial ones */
-                                       if (line[0] == '"' || line[0] == '\'') {
-                                               for (p = line; *p; p++)
-                                                       ;
-                                               if (--p == line) {
-                                                       fprintf(stderr, 
"unmatched %c\n", line[0]);
-                                                       continue;
-                                               } else if ((*p == '"' || *p == 
'\'') && *p != line[0]) {
-                                                       fprintf(stderr, 
"unexpected %c, expecting %c\n",
-                                                                       *p, 
line[0]);
-                                                       continue;
-                                               } else if (*p != line[0]) {
-                                                       fprintf(stderr, 
"unexpected end of string while "
-                                                                       
"looking for matching %c\n", line[0]);
-                                                       continue;
-                                               }
-                                               /* remove the quotes */
-                                               line++;
-                                               *p = '\0';
-                                       } else {
-                                               /* not quoted: lowercase it, 
and search for
-                                                * wildcards * and ?, replace 
them with SQL
-                                                * variants */
-                                               for (p = line; *p; p++) {
-                                                       *p = tolower((int) *p);
-                                                       if (*p == '*') {
-                                                               *p = '%';
-                                                               hasWildcard = 1;
-                                                       } else if (*p == '?') {
-                                                               *p = '_';
-                                                               hasWildcard = 1;
-                                                       } else if (*p == '.') {
-                                                               hasSchema = 1;
-                                                       }
+                                       /* lowercase the object, except for 
quoted parts */
+                                       q = line;
+                                       for (p = line; *p != '\0'; p++) {
+                                               switch (*p) {
+                                                       case '"':
+                                                               if (escaped) {
+                                                                       if (*(p 
+ 1) == '"') {
+                                                                               
/* SQL escape */
+                                                                               
*q++ = *p++;
+                                                                       } else {
+                                                                               
escaped = 0;
+                                                                       }
+                                                               } else {
+                                                                       escaped 
= 1;
+                                                               }
+                                                               break;
+                                                       default:
+                                                               if (!escaped) {
+                                                                       *q++ = 
tolower((int) *p);
+                                                                       if (*p 
== '*') {
+                                                                               
*p = '%';
+                                                                               
hasWildcard = 1;
+                                                                       } else 
if (*p == '?') {
+                                                                               
*p = '_';
+                                                                               
hasWildcard = 1;
+                                                                       } else 
if (*p == '.') {
+                                                                               
hasSchema = 1;
+                                                                       }
+                                                               } else {
+                                                                       *q++ = 
*p;
+                                                               }
+                                                               break;
                                                }
                                        }
+                                       *q = '\0';
+                                       if (escaped) {
+                                               fprintf(stderr, "unexpected end 
of string while "
+                                                               "looking for 
matching \"\n");
+                                               continue;
+                                       }
+
                                        if (*line && !hasWildcard) {
 #ifdef HAVE_POPEN
                                                stream *saveFD, *saveFD_raw;
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to