parser.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:4k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * parser.c
  4.  *
  5.  * Copyright (c) 1994, Regents of the University of California
  6.  *
  7.  *
  8.  * IDENTIFICATION
  9.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/parser/parser.c,v 1.39 1999/05/25 16:10:24 momjian Exp $
  10.  *
  11.  *-------------------------------------------------------------------------
  12.  */
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include "postgres.h"
  16. #include "nodes/pg_list.h"
  17. #include "parser/analyze.h"
  18. #include "parser/gramparse.h"
  19. #include "parser/parse_node.h"
  20. #include "parser/parser.h"
  21. #if defined(FLEX_SCANNER)
  22. extern void DeleteBuffer(void);
  23. #endif  /* FLEX_SCANNER */
  24. char    *parseString; /* the char* which holds the string to be
  25.  * parsed */
  26. List    *parsetree; /* result of parsing is left here */
  27. #ifdef SETS_FIXED
  28. static void fixupsets();
  29. static void define_sets();
  30. #endif
  31. /*
  32.  * parser-- returns a list of parse trees
  33.  */
  34. List *
  35. parser(char *str, Oid *typev, int nargs)
  36. {
  37. List    *queryList;
  38. int yyresult;
  39. init_io();
  40. parseString = pstrdup(str);
  41. parsetree = NIL; /* in case parser forgets to set it */
  42. parser_init(typev, nargs);
  43. yyresult = yyparse();
  44. #if defined(FLEX_SCANNER)
  45. DeleteBuffer();
  46. #endif  /* FLEX_SCANNER */
  47. clearerr(stdin);
  48. if (yyresult) /* error */
  49. return (List *) NULL;
  50. queryList = parse_analyze(parsetree, NULL);
  51. #ifdef SETS_FIXED
  52. /*
  53.  * Fixing up sets calls the parser, so it reassigns the global
  54.  * variable parsetree. So save the real parsetree.
  55.  */
  56. savetree = parsetree;
  57. foreach(parse, savetree)
  58. { /* savetree is really a list of parses */
  59. /* find set definitions embedded in query */
  60. fixupsets((Query *) lfirst(parse));
  61. }
  62. return savetree;
  63. #endif
  64. return queryList;
  65. }
  66. #ifdef SETS_FIXED
  67. static void
  68. fixupsets(Query *parse)
  69. {
  70. if (parse == NULL)
  71. return;
  72. if (parse->commandType == CMD_UTILITY) /* utility */
  73. return;
  74. if (parse->commandType != CMD_INSERT)
  75. return;
  76. define_sets(parse);
  77. }
  78. /* Recursively find all of the Consts in the parsetree.  Some of
  79.  * these may represent a set.  The value of the Const will be the
  80.  * query (a string) which defines the set. Call SetDefine to define
  81.  * the set, and store the OID of the new set in the Const instead.
  82.  */
  83. static void
  84. define_sets(Node *clause)
  85. {
  86. Oid setoid;
  87. Type t = typeidType(OIDOID);
  88. Oid typeoid = typeTypeId(t);
  89. Size oidsize = typeLen(t);
  90. bool oidbyval = typeByVal(t);
  91. if (clause == NULL)
  92. return;
  93. else if (IsA(clause, LispList))
  94. {
  95. define_sets(lfirst(clause));
  96. define_sets(lnext(clause));
  97. }
  98. else if (IsA(clause, Const))
  99. {
  100. if (get_constisnull((Const) clause) ||
  101. !get_constisset((Const) clause))
  102. return;
  103. setoid = SetDefine(((Const *) clause)->constvalue,
  104.    typeidTypeName(((Const *) clause)->consttype));
  105. set_constvalue((Const) clause, setoid);
  106. set_consttype((Const) clause, typeoid);
  107. set_constlen((Const) clause, oidsize);
  108. set_constypeByVal((Const) clause, oidbyval);
  109. }
  110. else if (IsA(clause, Iter))
  111. define_sets(((Iter *) clause)->iterexpr);
  112. else if (single_node(clause))
  113. return;
  114. else if (or_clause(clause) || and_clause(clause))
  115. {
  116. List    *temp;
  117. /* mapcan */
  118. foreach(temp, ((Expr *) clause)->args)
  119. define_sets(lfirst(temp));
  120. }
  121. else if (is_funcclause(clause))
  122. {
  123. List    *temp;
  124. /* mapcan */
  125. foreach(temp, ((Expr *) clause)->args)
  126. define_sets(lfirst(temp));
  127. }
  128. else if (IsA(clause, ArrayRef))
  129. define_sets(((ArrayRef *) clause)->refassgnexpr);
  130. else if (not_clause(clause))
  131. define_sets(get_notclausearg(clause));
  132. else if (is_opclause(clause))
  133. {
  134. define_sets(get_leftop(clause));
  135. define_sets(get_rightop(clause));
  136. }
  137. }
  138. #endif