/* File: aqldebug.c * Author: Richard Durbin (rd@sanger.ac.uk) * Copyright (C) J Thierry-Mieg and R Durbin, 1996 * ------------------------------------------------------------------- * Acedb is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt * ------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (MRC LMB, UK) rd@sanger.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr * * SCCS: $Id: aqldebug.c,v 1.36 2001/11/06 16:20:57 jcgs Exp $ * Description: * Exported functions: * HISTORY: * Last edited: Nov 9 12:05 1999 (fw) * * Nov 9 12:05 1999 (fw): converted to using ACEOUT * * Sep 7 17:12 1999 (fw): added IS_EXPR loc-type * * Mar 22 15:27 1999 (fw): changed debug-names for operators o reflect * their original name in the query. * * Aug 14 18:13 1998 (fw): added LIKE wildcard operator * * Aug 14 15:07 1998 (fw): added the bit for LOCAL_FIELD_NAME in prettyOut * * Aug 12 10:08 1998 (fw): added abs() ExprFunc * * Jul 27 11:05 1998 (fw): added PrettyOut bit for object constructor * * Jul 24 11:41 1998 (fw): added tableFunc column selection code * * Jul 15 15:41 1998 (fw): changed varname, as tmp-vars start with '_' now * * Jul 10 10:21 1998 (fw): fw's version after cleanup, but still pretty much the same * Created: Fri Oct 25 16:04:41 1996 (rd) *------------------------------------------------------------------- */ #include "acedb.h" #include "aceio.h" #include "waql/aql_.h" /************************************************************/ static void indent (ACEOUT debug_out, int ival); static char *varName (AqlNode *inNode); static int nestingLevel (AqlNode *inNode); /****************************************************************** ************************* public functions *********************** ******************************************************************/ /********** print out query structures, for debugging ***********/ /* the following three string tables have to correspond exactly to enum lists in aql_.h */ /********************* enum types for node->type ********************/ char* aqlNodeTypeName (AqlNodeType inType) { char* aqlNodeTypeNameTable[] = { "**type unset**", "TABLE_ASSIGN", "VAR_ASSIGN", /* added (fw-980716) */ "TABLE_VAR", "TABLE_OP", "TABLE_SFW", "TABLE_SFW_ALL", "TABLE_ORDER", "SORT_FIELD", "SORT_FIELD_NAME", "SORT_FIELD_EXPR", "SORT_QUALIFIER", "SELECT_FIELD", "FROM_LOC", "FROM_TABLE", "CLASS", "OBJECT", "LOC_VAR", "LOC_TABLE_FIELD", "LOC_TABLE_FIELD_NAME", "LOC_LOCAL_TAG", "LOC_LOCAL_TAG_NAME", "LOC_LOCAL_POS", "LOC_LOCAL_FIELD", "LOC_LOCAL_FIELD_NAME", "LOC_FOLLOW_TAG", "LOC_FOLLOW_TAG_NAME", "LOC_FOLLOW_POS", "LOC_METHOD", /* added (fw-980817) to replace EXPR_LOC_FUNC */ "EXPR_TABLE_FUNC", "EXPR_TABLE_FUNC_FIELD", /* added (fw-980723) */ "EXPR_TABLE_FUNC_FIELD_NAME", /* added (fw-980723) */ "EXPR_OP", "BOOL_EXISTS", "BOOL_EXISTS_TAG", "BOOL_COMPARISON", "BOOL_NOT", "BOOL_OP", "VAR", /* added (fw-980716) */ "TEXT", "INT", "FLOAT", "DATE", "KEY", "BOOL" } ; return aqlNodeTypeNameTable[inType]; } /* aqlNodeTypeName */ /******************* operators for node->op ***************/ char* aqlOpTypeName (AqlOpType inType) { char* aqlOpTypeNameTable[] = { "**op unset**", "union", "intersect", "diff", "asc", "desc", "=", "!=", "like", "<", ">", "<=", ">=", "not", "or", "and", "xor", "yeardiff", "monthdiff", "weekdiff", "daydiff", "hourdiff", "mindiff", "secdiff", "-", /* UMINUS */ "+", "-", "*", "/", "count", "first", "last", "sum", "min", "max", "avg", "abs", "modulo" } ; return aqlOpTypeNameTable[inType]; } /* aqlOpTypeName */ /************** enum source types for node->loc->source ********/ char* aqlLocSourceTypeName (AqlLocSourceType inType) { char* aqlLocSourceTypeNameTable[] = { "**src unset**", "IS_CLASS", "IS_ROW", "IS_COLUMN", "IS_OBJECT", "IS_LOCAL_TAG", "IS_FOLLOW_TAG", "IS_LOCAL_POS", "IS_FOLLOW_POS", "IS_METHOD", "IS_EXPR" }; return aqlLocSourceTypeNameTable[inType]; } /* aqlLocSourceTypeName */ static int lisply = 1; /************ Query **************/ void aqlQueryOut (ACEOUT debug_out, AqlQuery *inQuery) { if (inQuery) { aceOutPrint (debug_out, "\ncanonical query :\n\n "); #if 1 aqlNodeOut(debug_out, inQuery->root, 0, "canonical", FALSE); #endif aqlNodeOutPretty (debug_out, inQuery->root, FALSE, 1) ; aceOutPrint (debug_out, "\n\n") ; } return; } /* aqlQueryOut */ /************ recursive node dump **************/ void aqlNodeOut (ACEOUT debug_out, AqlNode *inNode, int ival, char *rel, BOOL suppress_next) { int outermost = 0; if (lisply) { indent (debug_out, ival*4) ; if (rel[strlen(rel)-1] != ' ') { aceOutPrint(debug_out, "%s:\n", rel); indent (debug_out, ival*4) ; outermost = 1; rel = "() "; } if (!inNode) { aceOutPrint(debug_out, "%c%c", rel[0], rel[1]); return; } aceOutPrint (debug_out, "%c%s", rel[0], aqlNodeTypeName(inNode->type)) ; if (inNode->name) aceOutPrint (debug_out, " \"%s\"", inNode->name) ; if (inNode->number) aceOutPrint (debug_out, " %d", inNode->number) ; if (inNode->op) aceOutPrint (debug_out, " %s", aqlOpTypeName(inNode->op)) ; if (inNode->type == nBOOL) aceOutPrint (debug_out, " %s", inNode->value.b?"TRUE":"FALSE") ; if (inNode->type == nTEXT) aceOutPrint (debug_out, " \"%s\"", inNode->value.s) ; if (inNode->type == nINT) aceOutPrint (debug_out, " %d", inNode->value.i) ; if (inNode->type == nFLOAT) aceOutPrint (debug_out, " %g", inNode->value.f) ; if (inNode->type == nDATE) aceOutPrint (debug_out, " %s", timeShow(inNode->value.t)) ; if (inNode->loc) { aceOutPrint (debug_out, " (loc"); if (1) { aceOutPrint (debug_out, " %lx", (unsigned long)(inNode->loc)); if (0) { aceOutPrint (debug_out, " def=%lx ", (unsigned long)(inNode->loc->definition)); } } if (1) { if (inNode->loc->definition == NULL) { aceOutPrint (debug_out, "NULL_definition!"); } else if ((inNode->loc->definition != inNode) && (inNode->loc->definition->type == nFROM_LOC)) { static int in_definition = 0; if (! in_definition) { in_definition = 1; aqlNodeOut (debug_out, inNode->loc->definition->left, ival+1, "<> ", TRUE); in_definition = 0; #if 0 indent (debug_out, ival*4) ; #endif } } } if (inNode->loc->source) aceOutPrint (debug_out, " %s", aqlLocSourceTypeName(inNode->loc->source)); aceOutPrint (debug_out, ")"); } if (inNode->left) aqlNodeOut (debug_out, inNode->left, ival+1, "() ", suppress_next) ; if (inNode->right) aqlNodeOut (debug_out, inNode->right, ival+1, "{} ", suppress_next) ; if (inNode->nxt && !suppress_next) aqlNodeOut (debug_out, inNode->nxt, ival+1, "[] ", suppress_next) ; aceOutPrint (debug_out, "%c", rel[1]); } else { if (!inNode) return ; indent (debug_out, ival) ; aceOutPrint (debug_out, "%s %s", rel, aqlNodeTypeName(inNode->type)) ; if (inNode->name) aceOutPrint (debug_out, " name \"%s\"", inNode->name) ; if (inNode->number) aceOutPrint (debug_out, " number %d", inNode->number) ; if (inNode->op) aceOutPrint (debug_out, " op %s", aqlOpTypeName(inNode->op)) ; if (inNode->type == nBOOL) aceOutPrint (debug_out, " %s", inNode->value.b?"TRUE":"FALSE") ; if (inNode->type == nTEXT) aceOutPrint (debug_out, " %s", inNode->value.s) ; if (inNode->type == nINT) aceOutPrint (debug_out, " %d", inNode->value.i) ; if (inNode->type == nFLOAT) aceOutPrint (debug_out, " %g", inNode->value.f) ; if (inNode->type == nDATE) aceOutPrint (debug_out, " %s", timeShow(inNode->value.t)) ; aceOutPrint (debug_out, "\t\t%lx", (unsigned long)inNode); if (inNode->loc) { aceOutPrint (debug_out, " (loc=%lx", (unsigned long)(inNode->loc)); if (inNode->loc->source) aceOutPrint (debug_out, ", %s", aqlLocSourceTypeName(inNode->loc->source)); aceOutPrint (debug_out, ")"); } if (inNode->left) aqlNodeOut (debug_out, inNode->left, ival+1, "left ", suppress_next) ; if (inNode->right) aqlNodeOut (debug_out, inNode->right, ival+1, "right ", suppress_next) ; if (inNode->nxt) aqlNodeOut (debug_out, inNode->nxt, ival, "next ", suppress_next) ; } if (outermost) { aceOutPrint(debug_out, "\n"); } return; } /* aqlNodeOut */ void aqlNodeValueOut (ACEOUT debug_out, AqlNode *inNode) { if (!inNode) { aceOutPrint (debug_out, "(NULL AqlNode) "); return ; } aceOutPrint (debug_out, "(`%s' [%c-value=", varName(inNode), inNode->vtype); if (inNode->isValue == NULLVAL) aceOutPrint (debug_out, "NULL") ; else if (inNode->isValue == FUZZYVAL) aceOutPrint (debug_out, "FUZZY") ; else /* TRUE */ { switch (inNode->vtype) { case 'k': case 'g': aceOutPrint (debug_out, "%x\"%s\"", inNode->value.k, name(inNode->value.k)) ; break; case 'i': aceOutPrint (debug_out, "%d", inNode->value.i) ; break; case 'f': aceOutPrint (debug_out, "%g", inNode->value.f) ; break; case 's': aceOutPrint (debug_out, "%s", inNode->value.s); break; case 't': aceOutPrint (debug_out, "%s", timeShow(inNode->value.t)); break; default: aceOutPrint (debug_out, "%x", inNode->value.k) ; } } aceOutPrint (debug_out, "]) ") ; return; } /* aqlNodeValueOut */ /**************** output a locators value ******************************/ void aqlLocOut (ACEOUT debug_out, char *text, AqlLoc *theLocator) { if (lisply) { aceOutPrint (debug_out, "%s ", text) ; aceOutPrint (debug_out, "name=%s", theLocator->definition->name); } else { aceOutPrint (debug_out, "%-10s ", text) ; aceOutPrint (debug_out, "loc=%lx", (unsigned long)theLocator) ; aceOutPrint (debug_out, ", (def=%lx)->name=%s", (unsigned long)theLocator->definition, theLocator->definition->name); } if (theLocator->isValue == NULLVAL) aceOutPrint (debug_out, " NULL\n") ; else if (theLocator->isValue == FUZZYVAL) aceOutPrint (debug_out, " FUZZY\n") ; else { aceOutPrint (debug_out, " type=%c", theLocator->type) ; switch (theLocator->type) { case 'k': case 'g': if (lisply) { aceOutPrint (debug_out, " value=%s", name(theLocator->value.k)) ; } else { aceOutPrint (debug_out, " value=%s(%x)", name(theLocator->value.k), theLocator->value.k) ; } break ; case 'i': aceOutPrint (debug_out, " value=%d", theLocator->value.i) ; break ; case 'f': aceOutPrint (debug_out, " value=%g", theLocator->value.f) ; break ; case 't': aceOutPrint (debug_out, " value=%s", timeShow(theLocator->value.t)) ; break ; case 's': aceOutPrint (debug_out, " value=%s", theLocator->value.s) ; break ; } aceOutPrint (debug_out, "\n") ; } return; } /* aqlLocOut */ void aqlCheckEnvOut(ACEOUT debug_out, char *text, AqlCheckEnv *env, int level) { indent(debug_out, level); aceOutPrint(debug_out, "CheckEnv at %s:\n", text); if (env == NULL) { indent(debug_out, level); aceOutPrint(debug_out, "null_env"); } else { if (env->pCurrDecl == NULL) { indent(debug_out, level); aceOutPrint(debug_out, "null curr_decl_pointer"); } else { indent(debug_out, level); aceOutPrint(debug_out, "curr_decl: "); if (*(env->pCurrDecl) == NULL) { aceOutPrint(debug_out, "null"); } else { aqlNodeOut(debug_out, *(env->pCurrDecl), level+1, "curr_decl", FALSE); } } if (env->pCurrWhere == NULL) { indent(debug_out, level); aceOutPrint(debug_out, "null curr_Where_pointer"); } else { indent(debug_out, level); aceOutPrint(debug_out, "curr_Where: "); if (*(env->pCurrWhere) == NULL) { aceOutPrint(debug_out, "null"); } else { aqlNodeOut(debug_out, *(env->pCurrWhere), level+1, "curr_Where", FALSE); } } if (env->currFromLoc == NULL) { indent(debug_out, level); aceOutPrint(debug_out, "null CurrFromLoc"); } else { aqlNodeOut(debug_out, env->currFromLoc, level+1, "curr_FromLoc", FALSE); } } } /****************************************************************** ************************ private functions *********************** ******************************************************************/ void aqlNodeOutPretty (ACEOUT debug_out, AqlNode *inNode, BOOL doBrackets, int ival) { if (!inNode) messcrash("NULL inNode in aqlNodeOutPretty()"); if (doBrackets && nestingLevel(inNode) > 1) { aceOutPrint (debug_out, "("); ival += 1; } switch (inNode->type) { case nTABLE_ASSIGN: aceOutPrint (debug_out, "@%s := ", varName(inNode)) ; ival += strlen(varName(inNode)) + 5; aqlNodeOutPretty (debug_out, inNode->left, FALSE, ival); ival -= strlen(varName(inNode)) + 5; if (inNode->nxt) { aceOutPrint (debug_out, ";"); indent (debug_out, ival); aqlNodeOutPretty (debug_out, inNode->nxt, FALSE, ival); } break ; case nVAR_ASSIGN: aceOutPrint (debug_out, "$%s := ", varName(inNode)) ; ival += strlen(varName(inNode)) + 5; aqlNodeOutPretty (debug_out, inNode->left, FALSE, ival); if (inNode->nxt) { aceOutPrint (debug_out, ";"); indent (debug_out, ival); aqlNodeOutPretty (debug_out, inNode->nxt, FALSE, ival); } break ; case nTABLE_VAR: aceOutPrint (debug_out, "@%s", varName(inNode)) ; break ; case nTABLE_OP: { int oldival = ival; aqlNodeOutPretty (debug_out, inNode->left, TRUE, ival); if (inNode->left->type != nTABLE_VAR) { indent (debug_out, ival); ival += 1; } aceOutPrint (debug_out, " %s ", aqlOpTypeName(inNode->op)) ; ival += (strlen(aqlOpTypeName(inNode->op)) + 2); if (inNode->left->type != nTABLE_VAR) { ival = oldival; indent (debug_out, ival); } aqlNodeOutPretty (debug_out, inNode->right, TRUE, ival); if (inNode->nxt) { aceOutPrint (debug_out, ";"); oldival = ival; indent (debug_out, ival); aqlNodeOutPretty (debug_out, inNode->nxt, FALSE, ival); } } break ; case nTABLE_SFW: { int oldival = ival; AqlNode *n=0; BOOL isSelectAll = FALSE; BOOL isFirstFromClause = TRUE; if (inNode->right && inNode->right->nxt == 0 && /* only one selectfield .. */ strcmp(varName(inNode->right), "") == 0 && /* .. is the default locator */ (inNode->right->loc && inNode->right->loc->source == IS_CLASS)) isSelectAll = TRUE; /* indent (debug_out, ival);*/ if (isSelectAll) { aceOutPrint (debug_out, "select all "); ival += 11; } else { aceOutPrint (debug_out, "select "); ival += 7; /* n loops through multiple select-fields */ n = inNode->right; while(n) { aqlNodeOutPretty (debug_out, n, FALSE, ival); /* LOC_VARs */ if (strcmp(varName(n), "") != 0) /* named variable */ { if (n->name && n->loc) ival += strlen(varName(n->loc->definition)) ; else ival += strlen(varName(n)); } else ival += 3; if (n->nxt) { aceOutPrint (debug_out, ", "); ival += 2; } n = n->nxt; } } ival = oldival + 2; n = inNode->left; /* first of a linked list of FROM_LOCs */ while (n) { if (!isSelectAll || !isFirstFromClause) indent (debug_out, ival); if (isFirstFromClause) { if (!isSelectAll) { aceOutPrint (debug_out, "from "); ival += 5; } isFirstFromClause = FALSE; } aqlNodeOutPretty (debug_out, n, FALSE, ival); if (n->nxt) aceOutPrint (debug_out, ", "); n = n->nxt; } if (inNode->nxt) { aceOutPrint (debug_out, ";"); ival = oldival; indent (debug_out, ival); aqlNodeOutPretty (debug_out, inNode->nxt, FALSE, ival); } } break ; case nTABLE_ORDER: { int oldival = ival; aqlNodeOutPretty (debug_out, inNode->left, FALSE, ival); /* table_expr */ ival += 2; indent (debug_out, ival); aceOutPrint (debug_out, "order") ; ival += 5; if (inNode->right) { aceOutPrint (debug_out, " by ") ; ival += 4; aqlNodeOutPretty (debug_out, inNode->right, FALSE, ival); /* SORT_FIELDs */ } else { if (inNode->op != oASC) { aceOutPrint (debug_out, " %s", aqlOpTypeName(inNode->op)); ival += (strlen(aqlOpTypeName(inNode->op)) + 2); } } ival = oldival ; if (inNode->nxt) { aceOutPrint (debug_out, ";"); indent (debug_out, ival); aqlNodeOutPretty (debug_out, inNode->nxt, FALSE, ival); /* another table_expr */ } } break ; case nSORT_FIELD: aceOutPrint (debug_out, ":%d", inNode->number) ; ival += strlen(messprintf(":%d", inNode->number)); if (inNode->left) { aceOutPrint (debug_out, " "); ival += 1; aqlNodeOutPretty (debug_out, inNode->left, FALSE, ival); /* qualifier */ } if (inNode->nxt) { aceOutPrint (debug_out, ", "); ival += 2; aqlNodeOutPretty (debug_out, inNode->nxt, FALSE, ival); } break ; case nSORT_FIELD_EXPR: aceOutPrint (debug_out, "******************") ; break ; case nSORT_QUALIFIER: if (inNode->op != oASC) aceOutPrint (debug_out, "%s", aqlOpTypeName(inNode->op)) ; break ; case nFROM_LOC: case nFROM_TABLE: { AqlNode *n; if (strcmp(varName(inNode), "") != 0) { aceOutPrint (debug_out, "%s in ", varName(inNode)); } /* output linked list of nodes hanging off the left Most commonly it starts with a LOC_VAR followed by nodes like LOC_FOLLOW_TAG */ for (n = inNode->left; n; n = n->nxt) aqlNodeOutPretty (debug_out, n, FALSE, ival); if (inNode->right) { ival += strlen(varName(inNode)) + 1; /* position 'where' below the 'in' in the decl */ indent (debug_out, ival); aceOutPrint (debug_out, "where "); aqlNodeOutPretty (debug_out, inNode->right, FALSE, ival+5); } } break ; /* case nFROM_TABLE: aceOutPrint (debug_out, "%s in ", varName(inNode)) ; aqlNodeOutPretty (debug_out, inNode->left, TRUE, ival); if (inNode->right) { indent (debug_out, ival); aceOutPrint (debug_out, "where ") ; aqlNodeOutPretty (debug_out, inNode->right, FALSE, ival+2); } if (inNode->nxt) { aceOutPrint (debug_out, ", ") ; indent (debug_out, ival); aqlNodeOutPretty (debug_out, inNode->nxt, FALSE, ival); } break ; */ case nCLASS: aceOutPrint (debug_out, "class %s", inNode->name) ; break ; case nOBJECT: aceOutPrint (debug_out, "object(") ; aqlNodeOutPretty (debug_out, inNode->left, FALSE, ival); aceOutPrint (debug_out, ", ") ; aqlNodeOutPretty (debug_out, inNode->right, FALSE, ival); aceOutPrint (debug_out, ")") ; break ; case nLOC_VAR: { if (strcmp(varName(inNode), "") != 0) /* named variable */ { if (inNode->name && inNode->loc) aceOutPrint (debug_out, "%s", varName(inNode->loc->definition)) ; else aceOutPrint (debug_out, "%s", varName(inNode)); } else { /* default iterator */ if (inNode->nxt && (inNode->nxt->type == nLOC_LOCAL_TAG || inNode->nxt->type == nLOC_LOCAL_POS || inNode->nxt->type == nLOC_LOCAL_FIELD || inNode->nxt->type == nLOC_FOLLOW_TAG || inNode->nxt->type == nLOC_FOLLOW_POS || inNode->nxt->type == nLOC_METHOD)) aceOutPrint (debug_out, ""); else aceOutPrint (debug_out, "->0"); /* class/row based def-loc * quoted in select clause */ } } break ; case nLOC_FOLLOW_TAG: aceOutPrint (debug_out, "->%s[0]", name(inNode->value.k)) ; break ; case nLOC_LOCAL_POS: aceOutPrint (debug_out, "[%d]", inNode->number) ; break ; case nLOC_LOCAL_TAG: aceOutPrint (debug_out, "[%s]", name(inNode->value.k)) ; break ; case nLOC_LOCAL_FIELD: if (inNode->name) aceOutPrint (debug_out, ":%s", inNode->name) ; else aceOutPrint (debug_out, ":%d", inNode->number) ; break ; case nLOC_FOLLOW_POS: aceOutPrint (debug_out, "->%d", inNode->number) ; break ; case nLOC_METHOD: aceOutPrint (debug_out, ".%s", inNode->name); break; case nLOC_TABLE_FIELD: aqlNodeOutPretty (debug_out, inNode->left, TRUE, ival+5); /* the safe_table */ aceOutPrint (debug_out, ":%d", inNode->number); break; case nEXPR_TABLE_FUNC: aceOutPrint (debug_out, "%s", aqlOpTypeName(inNode->op)) ; ival += strlen(aqlOpTypeName(inNode->op)); aqlNodeOutPretty (debug_out, inNode->left, TRUE, ival); /* safe_table */ break ; case nEXPR_TABLE_FUNC_FIELD: aceOutPrint (debug_out, "%s", aqlOpTypeName(inNode->op)) ; ival += strlen(aqlOpTypeName(inNode->op)) + 1; aqlNodeOutPretty (debug_out, inNode->left, TRUE, ival); /* safe_table */ ival -= strlen(aqlOpTypeName(inNode->op)) + 1; aceOutPrint (debug_out, ":%d", inNode->number) ; break ; case nEXPR_OP: if (inNode->op == oUMINUS) { aceOutPrint (debug_out, "%s", aqlOpTypeName(inNode->op)) ; aqlNodeOutPretty (debug_out, inNode->left, TRUE, ival); /* expr */ } else if (inNode->op == oPLUS || inNode->op == oMINUS || inNode->op == oTIMES || inNode->op == oDIVIDE) { aqlNodeOutPretty (debug_out, inNode->left, TRUE, ival); aceOutPrint (debug_out, " %s ", aqlOpTypeName(inNode->op)) ; aqlNodeOutPretty (debug_out, inNode->right, TRUE, ival); } else { aceOutPrint (debug_out, "%s(", aqlOpTypeName(inNode->op)) ; aqlNodeOutPretty (debug_out, inNode->left, FALSE, ival); if (inNode->right) { aceOutPrint (debug_out, ", "); aqlNodeOutPretty (debug_out, inNode->right, FALSE, ival); } aceOutPrint (debug_out, ")"); } break ; case nBOOL_EXISTS: aceOutPrint (debug_out, "exists ") ; aqlNodeOutPretty (debug_out, inNode->left, FALSE, ival); break ; case nBOOL_COMPARISON: aqlNodeOutPretty (debug_out, inNode->left, TRUE, ival); aceOutPrint (debug_out, " %s ", aqlOpTypeName(inNode->op)); aqlNodeOutPretty (debug_out, inNode->right, TRUE, ival); break ; case nBOOL_NOT: aceOutPrint (debug_out, "not ") ; aqlNodeOutPretty (debug_out, inNode->left, TRUE, ival); break ; case nBOOL_OP: aqlNodeOutPretty (debug_out, inNode->left, TRUE, ival); aceOutPrint (debug_out, " %s ", aqlOpTypeName(inNode->op)) ; aqlNodeOutPretty (debug_out, inNode->right, TRUE, ival); break ; case nVAR: aceOutPrint (debug_out, "$%s", varName(inNode)) ; break ; case nTEXT: aceOutPrint (debug_out, "\"%s\"", inNode->value.s) ; break ; case nINT: aceOutPrint (debug_out, "%d", inNode->value.i) ; break ; case nFLOAT: aceOutPrint (debug_out, "%g", inNode->value.f) ; break ; case nDATE: aceOutPrint (debug_out, "%s", timeShow(inNode->value.t)) ; break ; case nBOOL: aceOutPrint (debug_out, "%s", inNode->value.b ? "true" : "false") ; break; case nKEY: aceOutPrint (debug_out, "\"%s\"", name(inNode->value.k)); break; case nTABLE_SFW_ALL: case nSELECT_FIELD: case nBOOL_EXISTS_TAG: case nLOC_LOCAL_TAG_NAME: case nLOC_FOLLOW_TAG_NAME: case nSORT_FIELD_NAME: case nLOC_LOCAL_FIELD_NAME: case nLOC_TABLE_FIELD_NAME: case nEXPR_TABLE_FUNC_FIELD_NAME: messcrash("aqlNodeOutPretty() - %s should have been eliminated after check2", aqlNodeTypeName(inNode->type)); break ; } if (doBrackets && nestingLevel(inNode) > 1) aceOutPrint (debug_out, ")"); return; } /* aqlNodeOutPretty */ /************************************************************/ static void indent (ACEOUT debug_out, int ival) /** little utility for indentation **/ /** NB writes end of previous line **/ { int i ; aceOutPrint (debug_out, "\n") ; for (i = 0 ; i < ival ; ++i) aceOutPrint (debug_out, " ") ; return; } /* indent */ static char *varName (AqlNode *inNode) { char *s ; if (inNode->scope && inNode->scope->dict) s = dictName(inNode->scope->dict, inNode->number) ; else s = inNode->name ; if (!s) return "(null)"; if (strcmp(s, "_DEF") == 0) return ""; if (s[0] == '_') /* temporary variable */ return messprintf("tmp%s", s); return s ; } /* varName */ static int nestingLevel (AqlNode *inNode) { int left, right; if (!inNode) return 0; left = nestingLevel (inNode->left) + 1; right = nestingLevel (inNode->right) + 1; return left > right ? left : right; } /* nestingLevel */