home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / executor / ex_debug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-09  |  13.3 KB  |  589 lines

  1. /* ----------------------------------------------------------------
  2.  *   FILE
  3.  *    ex_debug.c
  4.  *    
  5.  *   DESCRIPTION
  6.  *    routines for manipulation of global debugging variables and
  7.  *    other miscellanious stuff.
  8.  *
  9.  *   INTERFACE ROUTINES
  10.  *    DebugVariableProcessCommand    - process a debugging command
  11.  *    DebugVariableFileSet        - process debugging cmds from a file
  12.  *
  13.  *   NOTES
  14.  *    None of the code in this file is essential to the executor.
  15.  *
  16.  *   IDENTIFICATION
  17.  *    $Header: /private/postgres/src/executor/RCS/ex_debug.c,v 1.7 1992/04/02 19:15:18 mer Exp $
  18.  * ----------------------------------------------------------------
  19.  */
  20. #include "executor/executor.h"
  21.  
  22.  RcsId("$Header: /private/postgres/src/executor/RCS/ex_debug.c,v 1.7 1992/04/02 19:15:18 mer Exp $");
  23.  
  24. /* ----------------
  25.  *    planner cost variables
  26.  * ----------------
  27.  */
  28. extern bool _enable_indexscan_;
  29. extern bool _enable_seqscan_;
  30. extern bool _enable_indexscan_;
  31. extern bool _enable_sort_;
  32. extern bool _enable_hash_;
  33. extern bool _enable_nestloop_;
  34. extern bool _enable_mergesort_;
  35. extern bool _enable_hashjoin_;
  36.  
  37.  
  38. /* ----------------
  39.  *    executor debugging hooks
  40.  * ----------------
  41.  */
  42. int _debug_hook_id_ = 0;
  43. HookNode _debug_hooks_[10];
  44.  
  45. /* ----------------
  46.  *    execution repetition
  47.  * ----------------
  48.  */
  49. int _exec_repeat_ = 1;
  50.  
  51. /* ----------------
  52.  *    Quiet flag - used to silence unwanted output
  53.  * ----------------
  54.  */
  55. int Quiet;
  56.  
  57. /* ----------------------------------------------------------------
  58.  *           debuging variable declaration
  59.  * ----------------------------------------------------------------
  60.  */
  61. /* ----------------
  62.  *    cpp hokum to make the table look nicer
  63.  *    (note: lack of spaces here is critical)
  64.  * ----------------
  65.  */
  66. #define debugconstantquote(x)"
  67. #define debugprefixquote(x)debugconstantquote(x)x
  68. #define debugquote(x)debugprefixquote(x)"
  69. #define DV(x) { debugquote(x), (Pointer) &x }
  70. #ifdef __STDC__
  71. #undef DV
  72. #define DV(x) { #x, (Pointer) &x }
  73. #endif
  74.  
  75. /* ----------------
  76.  *    DebuggingVariables is our table of debugging variables
  77.  * ----------------
  78.  */
  79. DebugVariable DebuggingVariables[] = {
  80.     /* ----------------
  81.      *    these first set are planner cost variables
  82.      * ----------------
  83.      */
  84.     DV(_enable_indexscan_),
  85.     DV(_enable_seqscan_),
  86.     DV(_enable_sort_),
  87.     DV(_enable_hash_),
  88.     DV(_enable_nestloop_),
  89.     DV(_enable_mergesort_),
  90.     DV(_enable_hashjoin_),
  91.     
  92.     
  93.     /* ----------------
  94.      *    these next are executor debug hook variables
  95.      * ----------------
  96.      */
  97.     DV(_debug_hook_id_),
  98.  
  99.     /* ----------------
  100.      *    next comes the executor repeat count
  101.      * ----------------
  102.      */
  103.     DV(_exec_repeat_),
  104.     
  105.     /* ----------------
  106.      *    an then there's the Quiet flag
  107.      * ----------------
  108.      */
  109.     DV(Quiet),
  110. };
  111.  
  112. #define NumberDebuggingVariables \
  113.     (sizeof(DebuggingVariables)/sizeof(DebuggingVariables[0]))
  114.  
  115. /* ----------------------------------------------------------------
  116.  *            support functions
  117.  * ----------------------------------------------------------------
  118.  */
  119. /* ----------------
  120.  *    SearchDebugVariables scans the table for the debug variable
  121.  *    entry given the name of the debugging variable.  It returns
  122.  *    NULL if the search fails.
  123.  *
  124.  *    Note: if the table gets larger than 50 items, then 
  125.  *    linear search should be replaced by matt's hash lookup.
  126.  *    Even so, it is only called by DebugVariableSet which is called
  127.  *    explicitly by the user so it only needs to be
  128.  *    interactively-acceptable.
  129.  * ----------------
  130.  */
  131. /**** xxref:
  132.  *           DebugVariableSet
  133.  *           DebugVariableProcessCommand
  134.  ****/
  135. static
  136. DebugVariablePtr
  137. SearchDebugVariables(debug_variable)
  138.     String debug_variable;
  139. {
  140.     int i;
  141.     String s;
  142.     
  143.     for (i=0; i<NumberDebuggingVariables; i++) {
  144.     s = DebuggingVariables[i].debug_variable;
  145.     if (strcmp(debug_variable, s) == 0)
  146.         return &(DebuggingVariables[i]);
  147.     }
  148.     
  149.     return NULL;
  150. }
  151.  
  152. /* ----------------
  153.  *    DebugVariableSet sets the value of the specified variable.
  154.  *    We assume debug_address is a pointer to an int.
  155.  * ----------------
  156.  */
  157. /**** xxref:
  158.  *           DebugVariableProcessCommand
  159.  ****/
  160. bool
  161. DebugVariableSet(debug_variable, debug_value)
  162.     String debug_variable;
  163.     int       debug_value;
  164. {
  165.     DebugVariablePtr p;
  166.     
  167.     p = SearchDebugVariables(debug_variable);
  168.     if (p == NULL)
  169.     return false;
  170.     
  171.     *((int *) p->debug_address) = debug_value;
  172.     
  173.     return true;
  174. }
  175.  
  176. /* ----------------
  177.  *    DebugVariableProcessCommand processes one of three
  178.  *    types of commands:
  179.  *
  180.  *    DEBUG variable value    - assign value to variable
  181.  *    DEBUG ? variable    - print value of variable
  182.  *    DEBUG P *        - print all variables & values
  183.  *    DEBUG X *        - initialize X debugging hook
  184.  *
  185.  *    It returns false if it couldn't parse the command.
  186.  * ----------------
  187.  */
  188. /**** xxref:
  189.  *           DebugVariableFileSet
  190.  ****/
  191. bool
  192. DebugVariableProcessCommand(buf)
  193.     char *buf;
  194. {
  195.     DebugVariablePtr p;
  196.     int     i;
  197.     char     s[128];
  198.     int     v;
  199.     bool     result;
  200.     
  201.     if (sscanf(buf, "DEBUG %s%d", s, &v) == 2) {
  202.     /* ----------------
  203.      *    set the variable in s to the value in v
  204.      * ----------------
  205.      */
  206.     result = DebugVariableSet(s, v);
  207.     if (! Quiet)
  208.         printf("DEBUG %s = %d\n", s, v);
  209.     return result;
  210.     
  211.     } else if (sscanf(buf, "DEBUG ? %s", s) == 1) {
  212.     /* ----------------
  213.      *    print the value of the variable in s
  214.      * ----------------
  215.      */
  216.         p = SearchDebugVariables(s);
  217.     if (p == NULL) {
  218.         printf("DEBUG [%s] no such variable\n", s);
  219.         return false;
  220.     }
  221.     v = *((int *) p->debug_address);
  222.     if (! Quiet)
  223.         printf("DEBUG %s = %d\n", s, v);
  224.     return true;
  225.     
  226.     } else if (sscanf(buf, "DEBUG P %s", s) == 1) {
  227.     /* ----------------
  228.      *    print the value of all variables
  229.      * ----------------
  230.      */
  231.     for (i=0; i<NumberDebuggingVariables; i++) {
  232.         v = *((int *) DebuggingVariables[i].debug_address);
  233.         if (! Quiet)
  234.         printf("DEBUG %s = %d\n",
  235.                DebuggingVariables[i].debug_variable,
  236.                v);
  237.     }
  238.     return true;
  239.     
  240.     } else if (sscanf(buf, "DEBUG X %s", s) == 1) {
  241.     MemoryContext oldContext;
  242.     
  243.     /* ----------------
  244.      *    assign the X debugging hooks in the top memory context
  245.      *    so that they aren't wiped out at end-transaction time.
  246.      * ----------------
  247.      */
  248.     oldContext = MemoryContextSwitchTo(TopMemoryContext);
  249.     
  250.     _debug_hook_id_ = 1;
  251.     _debug_hooks_[ _debug_hook_id_ ] = (HookNode) RMakeHookNode();
  252.     InitXHook( _debug_hooks_[ _debug_hook_id_ ] );
  253.  
  254.     (void) MemoryContextSwitchTo(oldContext);
  255.     return true;
  256.     }
  257.     
  258.     return false;
  259. }
  260.  
  261. /* ----------------
  262.  *    DebugVariableFileSet reads an entire file of
  263.  *    assignments and sets the values of the variables
  264.  *    in the file one at a time..
  265.  * ----------------
  266.  */
  267. /**** xxref:
  268.  *           InitializeExecutor
  269.  ****/
  270. void
  271. DebugVariableFileSet(filename)
  272.     String filename;
  273. {
  274.     FILE *dfile;
  275.     char buf[128];
  276.     char s[128];
  277.     int  v;
  278.     
  279.     dfile = fopen(filename, "r");
  280.     if (dfile == NULL)
  281.     return;
  282.     
  283.     bzero(buf, sizeof(buf));
  284.     
  285.     while (fgets(buf, 127, dfile) != NULL) {
  286.     if (buf[0] != '#')
  287.         DebugVariableProcessCommand(buf);
  288.     
  289.     bzero(buf, sizeof(buf));
  290.     }
  291.     
  292.     fclose(dfile);
  293. }
  294.  
  295. /* ----------------
  296.  *    parallel debugging stuff.  XXX comment me
  297.  * ----------------
  298.  */
  299. #ifdef PARALLELDEBUG
  300. #include "executor/paralleldebug.h"
  301. struct paralleldebuginfo ParallelDebugInfo[] = {
  302. /* 0 */ {"SharedLock", 0, 0, 0},
  303. /* 1 */ {"ExclusiveLock", 0, 0, 0},
  304. /* 2 */ {"FileRead", 0, 0, 0},
  305. /* 3 */ {"FileSeek", 0, 0, 0},
  306. };
  307. #define NPARALLELDEBUGINFO      4
  308.  
  309. PrintParallelDebugInfo(statfp)
  310. FILE *statfp;
  311. {
  312.     int i;
  313.     for (i=0; i<NPARALLELDEBUGINFO; i++) {
  314.     if (ParallelDebugInfo[i].count > 0)
  315.        fprintf(statfp, "!\t%sCount %d %sTime %.6f\n",
  316.         ParallelDebugInfo[i].name, ParallelDebugInfo[i].count,
  317.         ParallelDebugInfo[i].name, ParallelDebugInfo[i].time/1e6);
  318.       }
  319. }
  320.  
  321. ResetParallelDebugInfo()
  322. {
  323.     int i;
  324.     for (i=0; i<NPARALLELDEBUGINFO; i++) {
  325.     ParallelDebugInfo[i].count = 0;
  326.     ParallelDebugInfo[i].time = 0;
  327.      }
  328. }
  329. #endif /* PARALLELDEBUG */
  330.  
  331. /* ----------------------------------------------------------------
  332.  *            debugging functions
  333.  * ----------------------------------------------------------------
  334.  */
  335. /* ----------------
  336.  *    dbx does not understand macros so these functions are useful...
  337.  * ----------------
  338.  */
  339. Pointer
  340. FQdGetCommand(queryDesc)
  341.     List queryDesc;
  342. {
  343.     return (Pointer) QdGetCommand(queryDesc);
  344. }
  345.  
  346. Pointer
  347. FQdGetCount(queryDesc)
  348.     List queryDesc;
  349. {
  350.     return (Pointer) QdGetCount(queryDesc);
  351. }
  352.  
  353. Pointer
  354. FGetOperation(queryDesc)
  355.     List queryDesc;
  356. {
  357.     return (Pointer) GetOperation(queryDesc);
  358. }
  359.  
  360. Pointer
  361. FQdGetParseTree(queryDesc)
  362.     List queryDesc;
  363. {
  364.     return (Pointer) QdGetParseTree(queryDesc);
  365. }
  366.  
  367. Pointer
  368. FQdGetPlan(queryDesc)
  369.     List queryDesc;
  370. {
  371.     return (Pointer) QdGetPlan(queryDesc);
  372. }
  373.  
  374. Pointer
  375. FQdGetState(queryDesc)
  376.     List queryDesc;
  377. {
  378.     return (Pointer) QdGetState(queryDesc);
  379. }
  380.  
  381. Pointer
  382. FQdGetFeature(queryDesc)
  383.     List queryDesc;
  384. {
  385.     return (Pointer) QdGetFeature(queryDesc);
  386. }
  387.  
  388. Pointer
  389. Fparse_tree_range_table(queryDesc)
  390.     List queryDesc;
  391. {
  392.     return (Pointer) parse_tree_range_table(queryDesc);
  393. }
  394.  
  395. Pointer
  396. Fparse_tree_result_relation(queryDesc)
  397.     List queryDesc;
  398. {
  399.     return (Pointer) parse_tree_result_relation(queryDesc);
  400. }
  401.  
  402. /* ----------------------------------------------------------------
  403.  *    simple hook utility functions
  404.  * ----------------------------------------------------------------
  405.  */
  406.  
  407. /* ----------------
  408.  *    Simple hook functions
  409.  * ----------------
  410.  */
  411. void say_at_init()    { puts("at_init"); }
  412. void say_pre_proc()     { puts("pre_proc"); }
  413. void say_pre_end()    { puts("pre_end"); }
  414. void say_post_init()    { puts("post_init"); }
  415. void say_post_proc()    { puts("post_proc"); }
  416. void say_post_end()    { puts("post_end"); }
  417. void say_yow()        { puts("yow"); }
  418. void noop()        { return; }
  419.  
  420. /* ----------------
  421.  *    InitHook just initializes all the hook functions to noop
  422.  *    for the given hook node.
  423.  * ----------------
  424.  */
  425. void
  426. InitHook(hook)
  427.     HookNode hook;
  428. {
  429.     set_hook_at_initnode(hook, noop);
  430.     set_hook_pre_procnode(hook, noop);
  431.     set_hook_pre_endnode(hook, noop);
  432.     set_hook_post_initnode(hook, noop);
  433.     set_hook_post_procnode(hook, noop);
  434.     set_hook_post_endnode(hook, noop);
  435. }
  436.  
  437. /* ----------------
  438.  *    NoisyHook just initializes all the hook functions to
  439.  *    various say_xxx() routines for the given hook node.
  440.  * ----------------
  441.  */
  442. void
  443. NoisyHook(hook)
  444.     HookNode hook;
  445. {
  446.     set_hook_at_initnode(hook,   say_at_init);
  447.     set_hook_pre_procnode(hook,  say_pre_proc);
  448.     set_hook_pre_endnode(hook,   say_pre_end);
  449.     set_hook_post_initnode(hook, say_post_init);
  450.     set_hook_post_procnode(hook, say_post_proc);
  451.     set_hook_post_endnode(hook,  say_post_end);
  452. }
  453.  
  454. /* ----------------
  455.  *    GetNodeName
  456.  * ----------------
  457.  */
  458. /**** xxref:
  459.  *           nice_pre_proc
  460.  *           nice_pre_end
  461.  *           nice_post_init
  462.  *           nice_post_proc
  463.  *           nice_post_end
  464.  ****/
  465. String
  466. GetNodeName(node)
  467.     Node node;
  468. {
  469.     switch(NodeType(node)) {
  470.     case classTag(Result):
  471.     return (String) "Result";
  472.     
  473.     case classTag(Append):
  474.     return (String) "Append";
  475.     
  476.     case classTag(NestLoop):
  477.     return (String) "NestLoop";
  478.     
  479.     case classTag(MergeJoin):
  480.     return (String) "MergeJoin";
  481.     
  482.     case classTag(HashJoin):
  483.     return (String) "HashJoin";
  484.     
  485.     case classTag(SeqScan):
  486.     return (String) "SeqScan";
  487.     
  488.     case classTag(IndexScan):
  489.     return (String) "IndexScan";
  490.     
  491.     case classTag(Material):
  492.     return (String) "Material";
  493.     
  494.     case classTag(Sort):
  495.     return (String) "Sort";
  496.     
  497.     case classTag(Unique):
  498.     return (String) "Unique";
  499.     
  500.     case classTag(Hash):
  501.     return (String) "Hash";
  502.  
  503.     default:
  504.     return (String) "???";
  505.     }
  506. }
  507.  
  508. /* ----------------------------------------------------------------
  509.  *    the AddXXXNode functions are used to make last minute
  510.  *    hacks to the plans before the executor gets at them.
  511.  * ----------------------------------------------------------------
  512.  */
  513. /* ----------------
  514.  *    AddMaterialNode adds a material node to a plan
  515.  *
  516.  *    This is only supposed to be used in dbx for debugging..
  517.  *    -cim 1/26/89
  518.  * ----------------
  519.  */
  520. Plan
  521. AddMaterialNode(plan)
  522.     Plan plan;
  523. {
  524.     Material  material;
  525.     List      targetlist;
  526.     List      tl;
  527.     List      resdom;
  528.     
  529.     material = MakeMaterial(NULL);
  530.     targetlist = get_qptargetlist(plan);
  531.     set_qptargetlist((Plan) material, targetlist);
  532.     set_lefttree((Plan)material, (PlanPtr) plan);
  533.     return (Plan) material;
  534. }
  535.  
  536. /* ----------------
  537.  *    AddSortNode adds a sort node to a plan
  538.  *
  539.  *    This is only supposed to be used in dbx for debugging..
  540.  *    -cim 10/16/89
  541.  * ----------------
  542.  */
  543. Plan
  544. AddSortNode(plan, op)
  545.     Plan plan;
  546.     int op;
  547. {
  548.     Sort      sort;
  549.     List      targetlist;
  550.     List      tl;
  551.     Resdom      resdom;
  552.     
  553.     sort = MakeSort(NULL);
  554.     targetlist = get_qptargetlist(plan);
  555.     foreach (tl, targetlist) {
  556.     resdom = (Resdom) tl_resdom(CAR(tl));
  557.     set_reskey(resdom, 1);
  558.     set_reskeyop(resdom, (OperatorTupleForm) op);
  559.     }
  560.     set_qptargetlist((Plan)sort, targetlist);
  561.     set_lefttree((Plan)sort, (PlanPtr) plan);
  562.     set_tempid((Temp) sort, -1);
  563.     set_keycount((Temp) sort, 1);
  564.     return (Plan) sort;
  565. }
  566.  
  567. /* ----------------
  568.  *    AddUniqueNode adds a unique node to a plan
  569.  *
  570.  *    This is only supposed to be used in dbx for debugging..
  571.  *    -cim 1/30/89
  572.  * ----------------
  573.  */
  574. Plan
  575. AddUniqueNode(plan)
  576.     Plan plan;
  577. {
  578.     Unique    unique;
  579.     List      targetlist;
  580.     List      tl;
  581.     List      resdom;
  582.     
  583.     unique = MakeUnique(NULL);
  584.     targetlist = get_qptargetlist(plan);
  585.     set_qptargetlist((Plan) unique, targetlist);
  586.     set_lefttree((Plan) unique, (PlanPtr) plan);
  587.     return (Plan) unique;
  588. }
  589.