Update of /cvsroot/monetdb/pathfinder/compiler/debug
In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv29099

Modified Files:
        Makefile.ag 
Added Files:
        prettysql.c 
Log Message:

SQL pretty printer


Index: Makefile.ag
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/compiler/debug/Makefile.ag,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- Makefile.ag 3 Jan 2007 12:32:40 -0000       1.13
+++ Makefile.ag 5 Mar 2007 19:05:48 -0000       1.14
@@ -34,6 +34,7 @@
                coreprint.c \
                logdebug.c \
                physdebug.c \
-               prettyp.c 
+               prettyp.c \
+               prettysql.c
 }
 

--- NEW FILE: prettysql.c ---
/* -*- c-basic-offset:4; c-indentation-style:"k&r"; indent-tabs-mode:nil -*- */

/**
 * @file
 * 
 * Debugging: dump SQL language tree in
 * human readable format 
 *
 * Copyright Notice:
 * -----------------
 *
 * The contents of this file are subject to the Pathfinder Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of the License at
 * http://monetdb.cwi.nl/Legal/PathfinderLicense-1.1.html
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is the Pathfinder system.
 *
 * The Original Code has initially been developed by the Database &
 * Information Systems Group at the University of Konstanz, Germany and
 * is now maintained by the Database Systems Group at the Technische
 * Universitaet Muenchen, Germany.  Portions created by the University of
 * Konstanz and the Technische Universitaet Muenchen are Copyright (C)
 * 2000-2005 University of Konstanz and (C) 2005-2007 Technische
 * Universitaet Muenchen, respectively.  All Rights Reserved.
 *
 * $Id
 */

#include "pathfinder.h"

#include <stdlib.h>
#include <string.h>
#include "oops.h"

#include "prettysql.h"

#include "mem.h"
/* PFsql_t */
#include "sql.h"
/* PFty_str */
#include "types.h"
/* PFesc_string */
#include "pfstrings.h"

#include "prettyp.h"
#include <assert.h>

static char *ID[] = {
      [sql_tbl_name] = "table_name",
      [sql_add]      = "+",
      [sql_sub]      = "-",
      [sql_mul]      = "*",
      [sql_div]      = "/"
};

FILE *out = NULL;

/* forward declarations for the left site of grammar rules */
static void print_statements(PFsql_t*);
static void print_statement(PFsql_t*);
static void print_schema_name(PFsql_t*);
static void print_variable(PFsql_t*);
static void print_select_list(PFsql_t*);
static void print_clm_list(PFsql_t*);
static void print_aggrfunction(PFsql_t*);
static void print_common_table_expressions(PFsql_t *);
static void print_common_table_expression(PFsql_t*);
static void print_sort_key_expressions(PFsql_t*);
static void print_window_clause(PFsql_t*);
static void print_table_name(PFsql_t*);
static void print_subselect(PFsql_t*);
static void print_from_list(PFsql_t*);
static void print_tablereference(PFsql_t*);
static void print_fullselect(PFsql_t*);
static void print_expr(PFsql_t*);
static void print_correlation(PFsql_t*);
static void print_column_name(PFsql_t*);
static void print_schema_information(PFsql_t*);
static void print_schema_table(PFsql_t*);
static void print_schema_relcol(PFsql_t*);
static void print_join(PFsql_t*);

static void
print_sequence(PFsql_t *n)
{
   assert( n );
   assert( n->kind == sql_seq );

   print_schema_information(n->child[0]);
   PFprettyprintf("\n");
   print_statements(n->child[1]);
}   

/**
 * Convert the @a ident to a string.
 *
 * @param ident The identifier to convert.
 */
static char*
sql_column_name_str(PFsql_ident_t ident)
{
    char *attstr = NULL;
    char *tystr = NULL;
    char *res = NULL;
    size_t len = 0;

    /* check if special bits are set */
    if( (ident >> (ATT_BITS + TYPE_BITS)) & 0x00000007 ) {
        switch( (0x00000001) << ((ident >> (ATT_BITS + TYPE_BITS))
             & 0x00000007) ) {
            case sql_col_pre:    return "pre";
            case sql_col_level:  return "level";
            case sql_col_size: return "size";
            case sql_col_kind: return "kind";
            case sql_col_prop: return "prop";
            case sql_col_tag: return "tag";
            default: PFoops( OOPS_FATAL, 
                             "unknown special flag set");
        }
    }
    PFalg_att_t att = ((0x0000001F & ident) <= 0)?  0x00000000:
            (0x00000001 << (((0x0000001F) & ident)-1));
    PFalg_simple_type_t ty = (0x00000001 << (((0x000001E0) & ident)
                >> ATT_BITS));

    attstr = PFatt_str(att);
    tystr  = PFalg_simple_type_str(ty);

    len = strlen(attstr);
    len += strlen(tystr);

    res = (char*)PFmalloc(len * sizeof(char));
    snprintf(res, len+2, "%s-%s", attstr, tystr);

    return res;
}

static void
print_schema_information( PFsql_t *n )
{
    assert( n );

    switch( n->kind ) {
        case sql_schm_inf:
            print_schema_information( n->child[0] );
            fprintf(out, "\n");
            print_schema_information( n->child[1] );
            break;
        case sql_schm_cmmnt:
            fprintf(out, "-- !! ");
            fprintf(out, "%s", n->sem.comment );
            fprintf(out, " !!");
            break;
        case sql_schm_expr:
            fprintf(out, "-- ");
            print_schema_table( n->child[0] );
            print_schema_relcol( n->child[1] );
            break;
        default:
            PFoops( OOPS_FATAL,
                    "SQL generation doesn't support this kind "
                    "of schema information (%u)", n->kind );
    }
}

static void 
print_schema_relcol( PFsql_t *n )
{
    assert( n );
    
    fprintf(out, "-");
    switch( n->kind ) {
        case sql_clmn_name:
            fprintf(out, "%s", sql_column_name_str( n->sem.column.ident ));
            fprintf(out, ": ");
            fprintf(out, "%s", PFsql_column_name_str( n->sem.column.ident ));
            break;
        case sql_tbl_name:
            fprintf(out, "relation: ");
            fprintf(out, "%s", PFsql_table_str( n->sem.tablename.ident ));
            break;
        default:
            PFoops( OOPS_FATAL,
                    "In schema information is neither a "
                    "column nor a relation (%u)", n->kind);
    }
}

static void
print_schema_table( PFsql_t *n )
{
    assert( n );

    switch( n->kind ) {
        case sql_schm_doc:
            fprintf(out, "document");
            break;
        case sql_schm_res:
            fprintf(out, "result");
            break;
        default:
            PFoops( OOPS_FATAL, 
                    "SQL generation doesn't support this schema tables");
    }
}

/**
 * Print SQL statements.
 *
 * @param n SQL tree node.
 */
static void
print_statements(PFsql_t *n)
{
    switch( n->kind ) {
        case sql_with:
        {
            PFprettyprintf("WITH ");
            print_common_table_expressions( n->child[0] );
        } break;
       default:
        {
            /* TODO print string of node kind in the warning */
            print_statement( n );
            PFprettyprintf("\n");
        } break;
    }
}

static void
print_common_table_expressions(PFsql_t *n)
{
   assert( n );
   switch( n->kind ) {
       case sql_cmmn_tbl_expr:
       {
           print_common_table_expressions( n->child[0] );
           PFprettyprintf(", ");
           print_common_table_expression( n->child[1] );
       } break;
       default:
       {
           PFprettyprintf("%c", START_BLOCK);
           print_common_table_expression( n );
           PFprettyprintf("%c", END_BLOCK);
       } break;
   }
}

static void
print_common_table_expression(PFsql_t *n)
{
    assert( n );
    assert( n->kind == sql_bind );

    print_table_name( n->child[0] );
    PFprettyprintf(" AS (%c", START_BLOCK);
    print_fullselect( n->child[1] );
    PFprettyprintf("%c)", END_BLOCK);
}

static void
print_table_name(PFsql_t *n)
{
    assert( n );
    assert( n->kind == sql_tbl_name );

    PFprettyprintf("%s", PFsql_table_str( n->sem.tablename.ident ));
    /* the column-list has not to be specified in every case */ 
    if( n->child[0]) {
        PFprettyprintf("(");
        print_clm_list(n->child[0]);
        PFprettyprintf(")");
    }
}

static void
print_subselect(PFsql_t *n)
{
    assert( n );
    switch( n->kind ) {
        case sql_select:
        {
            PFprettyprintf("SELECT ");
            PFprettyprintf("%s%c", ( n->sem.select.distinct )?
                    "DISTINCT ":"", START_BLOCK);
            print_select_list( n->child[0] );

            PFprettyprintf("%c FROM %c", END_BLOCK, START_BLOCK);
            print_from_list( n->child[1] );
            PFprettyprintf("%c", END_BLOCK);
            /* where list is optional, we leave the where list
               to zero when its not specified */
            if( n->child[2]) {
                PFprettyprintf(" WHERE %c", START_BLOCK);
                print_expr( n->child[2]);
                PFprettyprintf("%c", END_BLOCK);
            }
            if( n->child[3]) {
                PFprettyprintf(" GROUP BY %c", START_BLOCK);
                print_clm_list( n->child[3] );
                PFprettyprintf("%c", END_BLOCK);
            }
        } break;
        default:
        {
            PFoops( OOPS_FATAL,
                    "Fullselect doesnt support this kind of node (%u).",
                    n->kind);
        } break;
    }
}

static void
print_from_list(PFsql_t *n)
{
    assert( n );

    switch( n->kind ) {
        case sql_frm_list:
            PFprettyprintf("%c", START_BLOCK);
            print_from_list( n->child[0] );
            PFprettyprintf("%c, %c", START_BLOCK, END_BLOCK);
            print_from_list( n->child[1] );
            PFprettyprintf("%c", END_BLOCK);
            break;
        case sql_alias:
        case sql_tb_name:
        case sql_tbl_name:
        case sql_select:
            print_tablereference( n );
            break;
        case sql_on:
            print_join( n );
            break;
        default:
            PFoops( OOPS_FATAL,
                    "This kind (%u) of statement is not supported by "
                    "fromlist", n->kind);
            break;
    }
}

static void
print_tablereference(PFsql_t* n)
{
    assert( n );

    switch( n->kind ) {
        case sql_alias:
        {
          PFprettyprintf("%c", START_BLOCK);
          print_tablereference( n->child[0] );
          PFprettyprintf("%c AS %c", END_BLOCK, START_BLOCK);
          print_correlation( n->child[1]);
          PFprettyprintf("%c", END_BLOCK);
        } break;
        case sql_tbl_name:
        {
            print_table_name( n );
        } break;
        case sql_tb_name:
        {
            print_schema_name( n->child[0] );
            PFprettyprintf(".");
            print_table_name( n->child[1] );
        } break;
        default:
        {
            PFprettyprintf("(");
            print_fullselect( n );
            PFprettyprintf(")");
        } break;
    }
}

static void
print_correlation( PFsql_t *n)
{
   assert( n );
   assert( n->kind == sql_crrltn_name );

   PFprettyprintf("%s",
       PFsql_correlation_name_str( n->sem.correlation.ident ));
}

static void
print_fullselect(PFsql_t *n)
{
    assert( n );
    switch( n->kind ) {
       case sql_union:
        {
            PFprettyprintf("(");
            print_fullselect(n->child[0]);
            PFprettyprintf(") UNION ALL (");
            print_fullselect(n->child[1]);
            PFprettyprintf(")");
        } break;
        case sql_diff:
        {
            PFprettyprintf("(");
            print_fullselect(n->child[0]);
            PFprettyprintf(") EXCEPT ALL (");
            print_fullselect(n->child[1]);
            PFprettyprintf(")");
        } break;

        default:
        {
            print_subselect( n );
        } break;
    }
}

static void
print_expr(PFsql_t *n)
{
    assert( n );

    switch( n->kind )
    {
        case sql_not:
         PFprettyprintf("NOT (");
         print_expr( n->child[0] );
         PFprettyprintf(")");
         break;
        case sql_max:
        {
            PFprettyprintf("MAX (");
            print_expr( n->child[0] );
            PFprettyprintf(")");
        } break;
        case sql_and:
        {
           PFprettyprintf("(");
           print_expr( n->child[0] );
           PFprettyprintf(" AND ");
           print_expr( n->child[1] );
           PFprettyprintf(")");
        } break;
        case sql_eq:
        {
          PFprettyprintf("(");
          print_expr( n->child[0] );
          PFprettyprintf(" = ");
          print_expr( n->child[1] );
          PFprettyprintf(")");
        } break;
        case sql_gt:
        {
          PFprettyprintf("(");
          print_expr( n->child[0] );
          PFprettyprintf(" > ");
          print_expr( n->child[1] );
          PFprettyprintf(")");
        } break;
        case sql_gteq:
        {
          PFprettyprintf("(");
          print_expr( n->child[0] );
          PFprettyprintf(" >= ");
          print_expr( n->child[1] );
          PFprettyprintf(")");
        } break;
        case sql_clmn_name:
        {
            if( n->crrlname != PF_SQL_CORRELATION_UNBOUNDED ) {
                PFprettyprintf("%s",
                    PFsql_correlation_name_str(n->crrlname));
                PFprettyprintf(".");
            }
            PFprettyprintf("%s",
                    PFsql_column_name_str(n->sem.column.ident));
        } break;
        case sql_lit_int:
        {
            PFprettyprintf("%i", n->sem.atom.val.i);
        } break;
        case sql_lit_str:
        {
            PFprettyprintf("'%s'", n->sem.atom.val.s);
        } break;
        case sql_cst:
            PFprettyprintf("CAST(");
            print_statement(n->child[0]);
            PFprettyprintf(" AS ");
            print_statement(n->child[1]);
            PFprettyprintf(")");
        break;
        /* expression : '(' expression '+' expression ')' */
        case sql_add:
        case sql_sub:
        case sql_mul:
        case sql_div:
        {
            PFprettyprintf("(");
            print_statement(n->child[0]);
            PFprettyprintf(" %s ", ID[n->kind]);
            print_statement(n->child[1]);
            PFprettyprintf(")");
        } break;
        case sql_like:
        {
            PFprettyprintf("(");
            print_statement(n->child[0]);
            PFprettyprintf(" LIKE  '%%");
            /* write the string without beginning and 
               trailing ' */
            assert (n->child[1]->kind == sql_lit_str);
            PFprettyprintf("%s", n->child[1]->sem.atom.val.s); 
            PFprettyprintf("\%%')");
        } break;
        default:
        {
            PFoops( OOPS_FATAL, "expression screwed up (%u)",
                    n->kind );
        } break;
    }
}
    
static void
print_select_list(PFsql_t *n)
{
    assert( n);
    
    switch( n->kind ) {
        case sql_slct_list:
            PFprettyprintf("%c", START_BLOCK);
            print_select_list( n->child[0] );
            PFprettyprintf(",%c %c", END_BLOCK, START_BLOCK);
            print_select_list( n->child[1] );
            PFprettyprintf("%c", END_BLOCK);
            break;
        default:
            print_statement(n);
            break;
    }
}

static void
print_part_expression(PFsql_t *n)
{
    assert( n );
    
    if( !((n->kind == sql_prt_expr) ||
            (n->kind == sql_list_terminator)) )
    {
        PFoops( OOPS_FATAL,
                "Pathfinder failed to print partition list" );
    }
   
    if( (n->kind == sql_list_terminator) &&
            (n->child[0] == NULL) && (n->child[1] == NULL) )
        return;

    print_statement(n->child[0]);
    if(!(n->child[1]->kind == sql_list_terminator ))
        PFprettyprintf(",");
    PFprettyprintf(" ");
    print_part_expression(n->child[1]);
}

static void
print_join( PFsql_t *n )
{
    assert( n );

    switch( n->kind ) {
        case sql_on:
            print_join( n->child[0] );
            PFprettyprintf(" ON ");
            print_expr( n->child[1] );
            break;
        case sql_innr_join:
            print_join( n->child[0] );
            PFprettyprintf(" INNER JOIN ");
            print_join( n->child[1] );
            break;
        case sql_outr_join:
            print_join( n->child[0] );
            PFprettyprintf(" RIGHT OUTER JOIN ");
            print_join( n->child[1] ); 
            break;
        case sql_alias:
        case sql_tb_name:
        case sql_tbl_name:
        case sql_select:
            print_tablereference( n );
            break;
        default:
            PFoops( OOPS_FATAL,
                    "SQL genereation doesn't support this kind "
                    "of join attribute (%u)", n->kind);
    }
}

static void
print_sort_key_expressions(PFsql_t *n)
{
    assert( n);
    
    switch( n->kind ) {
        case sql_srtky_expr:
            print_sort_key_expressions( n->child[0] );
            PFprettyprintf(", ");
            print_sort_key_expressions( n->child[1] );
            break;
        default:
            print_statement( n );
            break;
    }
}

static void
print_window_clause(PFsql_t* n)
{
    assert( n );
    assert( n->kind == sql_wnd_clause );

    if( n->child[0] ) {
        print_statement(n->child[0]);
    }
    if( n->child[1] ) {
        print_statement(n->child[1]);
    }
}

static void
print_clm_list(PFsql_t *n)
{
    assert( n );

    switch( n->kind ) {
        case sql_clmn_list:
            print_clm_list( n->child[0] );
            PFprettyprintf(", ");
            print_clm_list( n->child[1] );
            break;
        default:
            print_column_name( n );
    }
}

static void
print_column_name( PFsql_t *n )
{
    assert( n );
    assert( n->kind == sql_clmn_name );

    if( n->crrlname != PF_SQL_CORRELATION_UNBOUNDED ) {
        PFprettyprintf("%s", 
            PFsql_correlation_name_str(n->crrlname));
        PFprettyprintf(".");
    }
    PFprettyprintf("%s",
        PFsql_column_name_str(n->sem.column.ident));

}

static void
print_statement(PFsql_t *n)
{
    switch( n->kind ) {
        case sql_asc:
            PFprettyprintf("ASC");
            break;
        case sql_desc:
            PFprettyprintf("DESC");
            break;
        case sql_order:
            print_statement (n->child[0]);
            PFprettyprintf(" ");
            print_statement (n->child[1]);
            break;
        case sql_sum:
            PFprettyprintf("SUM(");
            print_statement( n->child[0] );
            PFprettyprintf(")");
            break;
        case sql_max:
        {
            PFprettyprintf("MAX (");
            print_statement( n->child[0] );
            PFprettyprintf(")");
        } break;
        case sql_count:
        {
            PFprettyprintf("COUNT (");
            PFprettyprintf("%s", (n->sem.count.distinct)?"DISTINCT ":"");
            print_statement( n->child[0] );
            PFprettyprintf(")"); 
        } break;
        case sql_eq:
            PFprettyprintf("(");
            print_statement( n->child[0] );
            PFprettyprintf(" = ");
            print_statement( n->child[1] );
            PFprettyprintf(")");
            break;
        case sql_prttn:
            PFprettyprintf("PARTITION BY ");
            print_part_expression(n->child[0]);
            break;
        case sql_ordr_by:
            PFprettyprintf("ORDER BY ");
            print_sort_key_expressions(n->child[0]);
            break;
        case sql_cst:
            PFprettyprintf("CAST(");
            print_statement(n->child[0]);
            PFprettyprintf(" AS ");
            print_statement(n->child[1]);
            PFprettyprintf(")");
            break;
        case sql_type:
            PFprettyprintf("%s", PFsql_simple_type_str(n->sem.type.t));
            break;
        case sql_tb_name:
            print_schema_name( n->child[0] );
            PFprettyprintf(".");
            print_table_name( n->child[1] );
            break;
        case sql_star:
            PFprettyprintf("*");
            break;
        case sql_union:
            {
                PFprettyprintf("(");
                print_statement( n->child[0] );
                PFprettyprintf(") UNION ALL (");
                print_statement( n->child[1] );
                PFprettyprintf(")");
            } break;
        case sql_diff:
            {
                PFprettyprintf("(");
                print_statement( n->child[0] );
                PFprettyprintf(") EXCEPT ALL (");
                print_statement( n->child[1] );
                PFprettyprintf(")");
            } break;
        case sql_alias:
            {
                if(n->child[0]->kind != sql_tbl_name ) {
                    PFprettyprintf("(");
                }
                print_statement( n->child[0] );
                if(n->child[0]->kind != sql_tbl_name ){
                    PFprettyprintf(")");
                } 
                PFprettyprintf(" ");
            } break;
        case sql_dot:
        {
            PFprettyprintf(".");
            print_statement( n->child[1] );
        } break;
        case sql_over:
        {   
           print_aggrfunction(n->child[0]);
           PFprettyprintf(" OVER (%c", START_BLOCK );
           print_window_clause(n->child[1]);
           PFprettyprintf("%c)", END_BLOCK);
        } break;
        case sql_bind:
        {
            print_variable( n->child[0] );
            PFprettyprintf(" AS (");
            print_statement( n->child[1] );
            PFprettyprintf(")");
        } break;
        case sql_clmn_name:
        {
            if( n->crrlname != PF_SQL_CORRELATION_UNBOUNDED ) {
                PFprettyprintf("%s", 
                    PFsql_correlation_name_str(n->crrlname));
                PFprettyprintf(".");
            }
            PFprettyprintf("%s",
                    PFsql_column_name_str(n->sem.column.ident));
        } break;
        case sql_tbl_name:
        {
            print_variable( n );
        } break;
        case sql_clmn_assign:
        {
            print_statement( n->child[0]);
            PFprettyprintf(" AS ");
            print_statement( n->child[1]);
        } break;
        case sql_lit_dec:
        {
            PFprettyprintf("%g", n->sem.atom.val.dec);
        } break;
        case sql_lit_int:
        {
            PFprettyprintf("%i", n->sem.atom.val.i);
        } break;
        case sql_lit_null:
        {
            PFprettyprintf("NULL");
        } break;
        case sql_lit_str:
        {
            PFprettyprintf("'%s'", n->sem.atom.val.s);
        } break;
        case sql_table_ref:
        {
            PFprettyprintf("%s", n->sem.table );
        } break;
       // case sql_select:
       // {
       //     PFprettyprintf("SELECT ");
       //     if( n->sem.select.distinct ) PFprettyprintf("DISTINCT ");
       //     print_select_list(n->child[0]);
       //     if(n->child[1])
       //     {
       //         PFprettyprintf(" FROM ");
       //     }
       // } break;
        /* expression : '(' expression '+' expression ')' */
        case sql_add:
        case sql_sub:
        case sql_mul:
        case sql_div:
        {
            PFprettyprintf("(");
            print_statement(n->child[0]);
            PFprettyprintf(" %s ", ID[n->kind]);
            print_statement(n->child[1]);
            PFprettyprintf(")");
        } break;
        case sql_like:
        {
            PFprettyprintf("(");
            print_statement(n->child[0]);
            PFprettyprintf(" LIKE  '%%");
            /* write the string without beginning and 
               trailing ' */
            assert (n->child[1]->kind == sql_lit_str);
            PFprettyprintf("%s", n->child[1]->sem.atom.val.s); 
            PFprettyprintf("\%%')");
        } break;
        case sql_gt:
        {
          PFprettyprintf("(");
          print_expr( n->child[0] );
          PFprettyprintf(" > ");
          print_expr( n->child[1] );
          PFprettyprintf(")");
        } break;
        case sql_gteq:
        {
          PFprettyprintf("(");
          print_expr( n->child[0] );
          PFprettyprintf(" >= ");
          print_expr( n->child[1] );
          PFprettyprintf(")");
        } break;

        default:
        {
            PFoops( OOPS_FATAL,
                    "Pathfinder doesn't support this kind "
                    "of SQL tree node (%i)", n->kind); 
        } break;
    }
}

static void
print_schema_name(PFsql_t *n)
{
    assert( n );
    assert( n->kind == sql_schm );

    PFprettyprintf("%s", n->sem.schema.str);
}

static void
print_aggrfunction(PFsql_t *n)
{
    switch( n->kind ) {
        case sql_rownumber:
        {
            PFprettyprintf("%cROWNUMBER()%c",
                START_BLOCK, END_BLOCK);
        } break;
        default:
        {
            PFoops( OOPS_FATAL,
                    "Pathfinder doesn't support this kind "
                    "of aggregat function");
        } break;
    }
}

static void
print_expression(PFsql_t *n)
{
    assert( n );
    PFprettyprintf("%c", START_BLOCK);
    switch( n->kind ) {
        case sql_expr_list:
        {
            print_expression(n->child[0]);
            PFprettyprintf(", ");
            print_expression(n->child[1]);
        } break;
        case sql_tbl_name:
        {
            print_variable (n);
        } break;
        case sql_sum:
        {
            PFprettyprintf("(");
            print_statement(n->child[0]);
            PFprettyprintf(" %s ", ID[n->kind]);
            print_statement(n->child[1]);
            PFprettyprintf(")");
        } break;
        default:
        {
            /* TODO insert NDEBUG */
            PFinfo( OOPS_NOTICE, 
                        "node: %s", ID[n->kind]);
            PFoops( OOPS_FATAL,
                    "Illegal SQL tree. SQL printer screwed up "
                    "(kind: %u).",
                    n->kind );
        } break;
    }
    PFprettyprintf("%c", END_BLOCK);
}

static void
print_variable( PFsql_t *n )
{
    assert( n );
    assert( n->kind == sql_tbl_name );

    PFprettyprintf("%s", PFsql_table_str( n->sem.tablename.ident ));
    if( n->child[0]) {
        PFprettyprintf("(");
        print_clm_list(n->child[0]);
        PFprettyprintf(")");
    }
}
/**
 * Recursively walk the SQL tree @a n and prettyprint
 * the query it represents.
 *
 * @param n SQL tree to prettyprint
 */
static void sql_pretty(PFsql_t *n)
{
    bool comma;

    if (!n)
        return;

    comma = true;

    print_sequence(n);
}

/**
 * Dump SQL tree @a t in pretty-printed form
 * into file @a f.
 *
 * @param f file to dump into
 * @param t root of SQL tree
 */
void
PFsql_pretty(FILE *f, PFsql_t *t)
{
    out = f;
    PFprettyprintf ("%c", START_BLOCK);
    sql_pretty (t);
    PFprettyprintf ("%c", END_BLOCK);

    (void) PFprettyp (f);

    fputc ('\n', f);
}

/* vim:set shiftwidth=4 expandtab: */


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Monetdb-pf-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-pf-checkins

Reply via email to