Changeset: 10001fd9ddc5 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/10001fd9ddc5
Modified Files:
        sql/server/sqlparse.c
Branch: clean_parser
Log Message:

initial printing added to sqlparse


diffs (224 lines):

diff --git a/sql/server/sqlparse.c b/sql/server/sqlparse.c
--- a/sql/server/sqlparse.c
+++ b/sql/server/sqlparse.c
@@ -127,6 +127,205 @@ mvc_new( bstream *rs, stream *ws) {
        return m;
 }
 
+char *
+qname_schema(dlist *qname)
+{
+       assert(qname && qname->h);
+
+       if (dlist_length(qname) == 2) {
+               return qname->h->data.sval;
+       } else if (dlist_length(qname) == 3) {
+               return qname->h->next->data.sval;
+       }
+       return NULL;
+}
+
+char *
+qname_schema_object(dlist *qname)
+{
+       assert(qname && qname->h);
+
+       if (dlist_length(qname) == 1) {
+               return qname->h->data.sval;
+       } else if (dlist_length(qname) == 2) {
+               return qname->h->next->data.sval;
+       } else if (dlist_length(qname) == 3) {
+               return qname->h->next->next->data.sval;
+       }
+       return "unknown";
+}
+
+
+static char * sp_symbol2string(mvc *sql, symbol *se, int expression, char 
**err);
+
+static char *
+dlist2string(mvc *sql, dlist *l, int expression, char **err)
+{
+       char *b = NULL;
+       dnode *n;
+
+       for (n=l->h; n; n = n->next) {
+               char *s = NULL;
+
+               if (n->type == type_string && n->data.sval)
+                       s = sa_strdup(sql->ta, n->data.sval);
+               else if (n->type == type_symbol)
+                       s = sp_symbol2string(sql, n->data.sym, expression, err);
+
+               if (!s)
+                       return NULL;
+               if (b) {
+                       char *o = SA_NEW_ARRAY(sql->ta, char, strlen(b) + 
strlen(s) + 2);
+                       if (o)
+                               stpcpy(stpcpy(stpcpy(o, b), "."), s);
+                       b = o;
+                       if (b == NULL)
+                               return NULL;
+               } else {
+                       b = s;
+               }
+       }
+       return b;
+}
+
+static const char *
+symbol_escape_ident(allocator *sa, const char *s)
+{
+       char *res = NULL;
+       if (s) {
+               size_t l = strlen(s);
+               char *r = SA_NEW_ARRAY(sa, char, (l * 2) + 1);
+
+               res = r;
+               while (*s) {
+                       if (*s == '"')
+                               *r++ = '"';
+                       *r++ = *s++;
+               }
+               *r = '\0';
+       }
+       return res;
+}
+
+char *
+sp_symbol2string(mvc *sql, symbol *se, int expression, char **err)
+{
+       /* inner sp_symbol2string uses the temporary allocator */
+       switch (se->token) {
+       case SQL_NOP: {
+               dnode *lst = se->data.lval->h, *ops = NULL, *aux;
+               const char *op = symbol_escape_ident(sql->ta, 
qname_schema_object(lst->data.lval)),
+                                  *sname = symbol_escape_ident(sql->ta, 
qname_schema(lst->data.lval));
+               int i = 0, nargs = 0;
+               char** inputs = NULL, *res;
+               size_t inputs_length = 0, extra = sname ? strlen(sname) + 3 : 0;
+
+               if (lst->next->next->data.lval)
+                       ops = lst->next->next->data.lval->h;
+
+               for (aux = ops; aux; aux = aux->next)
+                       nargs++;
+               if (!(inputs = SA_ZNEW_ARRAY(sql->ta, char*, nargs)))
+                       return NULL;
+
+               for (aux = ops; aux; aux = aux->next) {
+                       if (!(inputs[i] = sp_symbol2string(sql, aux->data.sym, 
expression, err))) {
+                               return NULL;
+                       }
+                       inputs_length += strlen(inputs[i]);
+                       i++;
+               }
+
+               if ((res = SA_NEW_ARRAY(sql->ta, char, extra + strlen(op) + 
inputs_length + 3 + (nargs - 1 /* commas */) + 2))) {
+                       char *concat = res;
+                       if (sname)
+                               concat = stpcpy(stpcpy(stpcpy(res, "\""), 
sname), "\".");
+                       concat = stpcpy(stpcpy(stpcpy(concat, "\""), op), 
"\"(");
+                       i = 0;
+                       for (aux = ops; aux; aux = aux->next) {
+                               concat = stpcpy(concat, inputs[i]);
+                               if (aux->next)
+                                       concat = stpcpy(concat, ",");
+                               i++;
+                       }
+                       concat = stpcpy(concat, ")");
+               }
+               return res;
+       }
+       case SQL_PARAMETER:
+               return sa_strdup(sql->ta, "?");
+       case SQL_NULL:
+               return sa_strdup(sql->ta, "NULL");
+       case SQL_ATOM:{
+               AtomNode *an = (AtomNode *) se;
+               if (an && an->a)
+                       return atom2sql(sql->ta, an->a, sql->timezone);
+               else
+                       return sa_strdup(sql->ta, "NULL");
+       }
+       case SQL_NEXT: {
+               const char *seq = symbol_escape_ident(sql->ta, 
qname_schema_object(se->data.lval)),
+                                  *sname = qname_schema(se->data.lval);
+               char *res;
+
+               if (!sname)
+                       sname = sql->session->schema->base.name;
+               sname = symbol_escape_ident(sql->ta, sname);
+
+               if ((res = SA_NEW_ARRAY(sql->ta, char, strlen("next value for 
\"") + strlen(sname) + strlen(seq) + 5)))
+                       stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "next value for 
\""), sname), "\".\""), seq), "\"");
+               return res;
+       }       break;
+       case SQL_IDENT:
+       case SQL_COLUMN: {
+               /* can only be variables */
+               dlist *l = se->data.lval;
+               assert(l->h->type != type_lng);
+               if (expression && dlist_length(l) == 1 && l->h->type == 
type_string) {
+                       /* when compiling an expression, a column of a table 
might be present in the symbol, so we need this case */
+                       const char *op = symbol_escape_ident(sql->ta, 
l->h->data.sval);
+                       char *res;
+
+                       if ((res = SA_NEW_ARRAY(sql->ta, char, strlen(op) + 3)))
+                               stpcpy(stpcpy(stpcpy(res, "\""), op), "\"");
+                       return res;
+               } else if (expression && dlist_length(l) == 2 && l->h->type == 
type_string && l->h->next->type == type_string) {
+                       const char *first = symbol_escape_ident(sql->ta, 
l->h->data.sval),
+                                          *second = 
symbol_escape_ident(sql->ta, l->h->next->data.sval);
+                       char *res;
+
+                       if (!first || !second)
+                               return NULL;
+                       if ((res = SA_NEW_ARRAY(sql->ta, char, strlen(first) + 
strlen(second) + 6)))
+                               stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "\""), 
first), "\".\""), second), "\"");
+                       return res;
+               } else {
+                       char *e = dlist2string(sql, l, expression, err);
+                       if (e)
+                               *err = e;
+                       return NULL;
+               }
+       }
+       case SQL_CAST: {
+               dlist *dl = se->data.lval;
+               char *val = NULL, *tpe = NULL, *res;
+
+               if (!(val = sp_symbol2string(sql, dl->h->data.sym, expression, 
err)) || !(tpe = subtype2string2(sql->ta, &dl->h->next->data.typeval)))
+                       return NULL;
+               if ((res = SA_NEW_ARRAY(sql->ta, char, strlen(val) + 
strlen(tpe) + 11)))
+                       stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "cast("), val), 
" as "), tpe), ")");
+               return res;
+       }
+       default: {
+               const char msg[] = "SQL feature not yet available for 
expressions and default values: ";
+               char *tok_str = token2string(se->token);
+               if ((*err = SA_NEW_ARRAY(sql->ta, char, strlen(msg) + 
strlen(tok_str) + 1)))
+                       stpcpy(stpcpy(*err, msg), tok_str);
+       }
+       }
+       return NULL;
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -155,7 +354,13 @@ main(int argc, char *argv[])
                return -4;
        while ((err = sqlparse(m)) == 0 && m->scanner.rs->pos < 
m->scanner.rs->len) {
                if (m->sym) {
-                       printf("parsed\n");
+                       char *err = NULL;
+                       char *res = sp_symbol2string(m, m->sym, 1, &err);
+
+                       if (err)
+                               printf("ERROR: %s\n", err);
+                       else
+                               printf("SYM: %s\n", res);
                }
                scanner_query_processed(&m->scanner);
                m->sym = NULL;
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to