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

数据库系统

开发平台:

Unix_Linux

  1. /**********************************************************************
  2.  * pl_comp.c - Compiler part of the PL/pgSQL
  3.  *   procedural language
  4.  *
  5.  * IDENTIFICATION
  6.  *   $Header: /usr/local/cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.7 1999/05/25 16:15:17 momjian Exp $
  7.  *
  8.  *   This software is copyrighted by Jan Wieck - Hamburg.
  9.  *
  10.  *   The author hereby grants permission  to  use,  copy, modify,
  11.  *   distribute,  and license this software and its documentation
  12.  *   for any purpose, provided that existing copyright notices are
  13.  *   retained in all  copies  and  that this notice is included
  14.  *   verbatim in any distributions. No written agreement, license,
  15.  *   or  royalty  fee is required for any of the authorized uses.
  16.  *   Modifications to this software may be  copyrighted  by  their
  17.  *   author  and  need  not  follow  the licensing terms described
  18.  *   here, provided that the new terms are  clearly  indicated  on
  19.  *   the first page of each file where they apply.
  20.  *
  21.  *   IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY
  22.  *   PARTY  FOR  DIRECT, INDIRECT, SPECIAL,   INCIDENTAL,  OR
  23.  *   CONSEQUENTIAL   DAMAGES  ARISING OUT  OF  THE  USE  OF  THIS
  24.  *   SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
  25.  *   IF  THE  AUTHOR  HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
  26.  *   DAMAGE.
  27.  *
  28.  *   THE  AUTHOR  AND DISTRIBUTORS  SPECIFICALLY  DISCLAIM ANY
  29.  *   WARRANTIES,  INCLUDING,  BUT NOT  LIMITED  TO,  THE IMPLIED
  30.  *   WARRANTIES  OF  MERCHANTABILITY, FITNESS  FOR  A  PARTICULAR
  31.  *   PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON
  32.  *   AN "AS IS" BASIS, AND THE AUTHOR AND  DISTRIBUTORS  HAVE  NO
  33.  *   OBLIGATION   TO PROVIDE   MAINTENANCE,  SUPPORT,  UPDATES,
  34.  *   ENHANCEMENTS, OR MODIFICATIONS.
  35.  *
  36.  **********************************************************************/
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <stdarg.h>
  40. #include <unistd.h>
  41. #include <fcntl.h>
  42. #include <string.h>
  43. #include <ctype.h>
  44. #include "plpgsql.h"
  45. #include "pl.tab.h"
  46. #include "executor/spi.h"
  47. #include "commands/trigger.h"
  48. #include "utils/elog.h"
  49. #include "utils/builtins.h"
  50. #include "fmgr.h"
  51. #include "access/heapam.h"
  52. #include "utils/syscache.h"
  53. #include "utils/catcache.h"
  54. #include "catalog/catname.h"
  55. #include "catalog/pg_proc.h"
  56. #include "catalog/pg_type.h"
  57. #include "catalog/pg_class.h"
  58. #include "catalog/pg_attribute.h"
  59. #include "catalog/pg_attrdef.h"
  60. /* ----------
  61.  * Variables in the parser that shouldn't go into plpgsql.h
  62.  * ----------
  63.  */
  64. extern PLPGSQL_YYSTYPE plpgsql_yylval;
  65. extern int plpgsql_yylineno;
  66. extern char plpgsql_yytext[];
  67. void plpgsql_yyerror(const char *s);
  68. /* ----------
  69.  * Our own local and global variables
  70.  * ----------
  71.  */
  72. static int datums_alloc;
  73. int plpgsql_nDatums;
  74. PLpgSQL_datum **plpgsql_Datums;
  75. static int datums_last = 0;
  76. int plpgsql_error_lineno;
  77. char    *plpgsql_error_funcname;
  78. int plpgsql_DumpExecTree = 0;
  79. PLpgSQL_function *plpgsql_curr_compile;
  80. /* ----------
  81.  * Local function declarations
  82.  * ----------
  83.  */
  84. static char *xlateSqlType(char *name);
  85. /* ----------
  86.  * plpgsql_compile Given a pg_proc's oid, make
  87.  * an execution tree for it.
  88.  * ----------
  89.  */
  90. PLpgSQL_function *
  91. plpgsql_compile(Oid fn_oid, int functype)
  92. {
  93. int parse_rc;
  94. HeapTuple procTup;
  95. Form_pg_proc procStruct;
  96. HeapTuple typeTup;
  97. Form_pg_type typeStruct;
  98. char    *proc_source;
  99. PLpgSQL_function *function;
  100. PLpgSQL_var *var;
  101. PLpgSQL_row *row;
  102. PLpgSQL_rec *rec;
  103. int i;
  104. int arg_varnos[MAXFMGRARGS];
  105. /* ----------
  106.  * Initialize the compiler
  107.  * ----------
  108.  */
  109. plpgsql_ns_init();
  110. plpgsql_ns_push(NULL);
  111. plpgsql_DumpExecTree = 0;
  112. datums_alloc = 128;
  113. plpgsql_nDatums = 0;
  114. plpgsql_Datums = palloc(sizeof(PLpgSQL_datum *) * datums_alloc);
  115. datums_last = 0;
  116. /* ----------
  117.  * Lookup the pg_proc tuple by Oid
  118.  * ----------
  119.  */
  120. procTup = SearchSysCacheTuple(PROOID,
  121.   ObjectIdGetDatum(fn_oid),
  122.   0, 0, 0);
  123. if (!HeapTupleIsValid(procTup))
  124. elog(ERROR, "plpgsql: cache lookup from pg_proc failed");
  125. /* ----------
  126.  * Setup the scanner input and error info
  127.  * ----------
  128.  */
  129. procStruct = (Form_pg_proc) GETSTRUCT(procTup);
  130. proc_source = textout(&(procStruct->prosrc));
  131. plpgsql_setinput(proc_source, functype);
  132. plpgsql_error_funcname = nameout(&(procStruct->proname));
  133. plpgsql_error_lineno = 0;
  134. /* ----------
  135.  * Create the new function node
  136.  * ----------
  137.  */
  138. function = malloc(sizeof(PLpgSQL_function));
  139. memset(function, 0, sizeof(PLpgSQL_function));
  140. plpgsql_curr_compile = function;
  141. function->fn_functype = functype;
  142. function->fn_oid = fn_oid;
  143. function->fn_name = strdup(nameout(&(procStruct->proname)));
  144. switch (functype)
  145. {
  146. case T_FUNCTION:
  147. /* ----------
  148.  * Normal function has a defined returntype
  149.  * ----------
  150.  */
  151. function->fn_rettype = procStruct->prorettype;
  152. function->fn_retset = procStruct->proretset;
  153. /* ----------
  154.  * Lookup the functions return type
  155.  * ----------
  156.  */
  157. typeTup = SearchSysCacheTuple(TYPOID,
  158.   ObjectIdGetDatum(procStruct->prorettype), 0, 0, 0);
  159. if (!HeapTupleIsValid(typeTup))
  160. {
  161. plpgsql_comperrinfo();
  162. elog(ERROR, "cache lookup for return type %u failed",
  163.  procStruct->prorettype);
  164. }
  165. typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
  166. if (typeStruct->typrelid != InvalidOid)
  167. function->fn_retistuple = true;
  168. else
  169. {
  170. function->fn_retbyval = typeStruct->typbyval;
  171. function->fn_rettyplen = typeStruct->typlen;
  172. fmgr_info(typeStruct->typinput, &(function->fn_retinput));
  173. }
  174. /* ----------
  175.  * Create the variables for the procedures parameters
  176.  * ----------
  177.  */
  178. for (i = 0; i < procStruct->pronargs; i++)
  179. {
  180. char buf[256];
  181. /* ----------
  182.  * Get the parameters type
  183.  * ----------
  184.  */
  185. typeTup = SearchSysCacheTuple(TYPOID,
  186.   ObjectIdGetDatum(procStruct->proargtypes[i]), 0, 0, 0);
  187. if (!HeapTupleIsValid(typeTup))
  188. {
  189. plpgsql_comperrinfo();
  190. elog(ERROR, "cache lookup for argument type %u failed",
  191.  procStruct->proargtypes[i]);
  192. }
  193. typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
  194. if (typeStruct->typrelid != InvalidOid)
  195. {
  196. /* ----------
  197.  * For tuple type parameters, we set up a record
  198.  * of that type
  199.  * ----------
  200.  */
  201. sprintf(buf, "%s%%rowtype", nameout(&(typeStruct->typname)));
  202. if (plpgsql_parse_wordrowtype(buf) != T_ROW)
  203. {
  204. plpgsql_comperrinfo();
  205. elog(ERROR, "cannot get tuple struct of argument %d", i + 1);
  206. }
  207. row = plpgsql_yylval.row;
  208. sprintf(buf, "$%d", i + 1);
  209. row->refname = strdup(buf);
  210. plpgsql_adddatum((PLpgSQL_datum *) row);
  211. plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW, row->rowno, buf);
  212. arg_varnos[i] = row->rowno;
  213. }
  214. else
  215. {
  216. /* ----------
  217.  * Normal parameters get a var node
  218.  * ----------
  219.  */
  220. var = malloc(sizeof(PLpgSQL_var));
  221. memset(var, 0, sizeof(PLpgSQL_var));
  222. var->datatype = malloc(sizeof(PLpgSQL_type));
  223. memset(var->datatype, 0, sizeof(PLpgSQL_type));
  224. sprintf(buf, "$%d", i + 1);
  225. var->dtype = PLPGSQL_DTYPE_VAR;
  226. var->refname = strdup(buf);
  227. var->lineno = 0;
  228. var->datatype->typname = strdup(nameout(&(typeStruct->typname)));
  229. var->datatype->typoid = procStruct->proargtypes[i];
  230. fmgr_info(typeStruct->typinput, &(var->datatype->typinput));
  231. var->datatype->typbyval = typeStruct->typbyval;
  232. var->datatype->atttypmod = -1;
  233. var->isconst = true;
  234. var->notnull = false;
  235. var->default_val = NULL;
  236. plpgsql_adddatum((PLpgSQL_datum *) var);
  237. plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, buf);
  238. arg_varnos[i] = var->varno;
  239. }
  240. }
  241. break;
  242. case T_TRIGGER:
  243. /* ----------
  244.  * Trigger procedures return type is unknown yet
  245.  * ----------
  246.  */
  247. function->fn_rettype = InvalidOid;
  248. function->fn_retbyval = false;
  249. function->fn_retistuple = true;
  250. function->fn_retset = false;
  251. /* ----------
  252.  * Add the record for referencing NEW
  253.  * ----------
  254.  */
  255. rec = malloc(sizeof(PLpgSQL_rec));
  256. memset(rec, 0, sizeof(PLpgSQL_rec));
  257. rec->dtype = PLPGSQL_DTYPE_REC;
  258. rec->refname = strdup("new");
  259. plpgsql_adddatum((PLpgSQL_datum *) rec);
  260. plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->recno, rec->refname);
  261. function->new_varno = rec->recno;
  262. /* ----------
  263.  * Add the record for referencing OLD
  264.  * ----------
  265.  */
  266. rec = malloc(sizeof(PLpgSQL_rec));
  267. memset(rec, 0, sizeof(PLpgSQL_rec));
  268. rec->dtype = PLPGSQL_DTYPE_REC;
  269. rec->refname = strdup("old");
  270. plpgsql_adddatum((PLpgSQL_datum *) rec);
  271. plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, rec->recno, rec->refname);
  272. function->old_varno = rec->recno;
  273. /* ----------
  274.  * Add the variable tg_name
  275.  * ----------
  276.  */
  277. var = malloc(sizeof(PLpgSQL_var));
  278. memset(var, 0, sizeof(PLpgSQL_var));
  279. var->dtype = PLPGSQL_DTYPE_VAR;
  280. var->refname = strdup("tg_name");
  281. var->lineno = 0;
  282. plpgsql_parse_word("name");
  283. var->datatype = plpgsql_yylval.dtype;
  284. var->isconst = false;
  285. var->notnull = false;
  286. var->default_val = NULL;
  287. plpgsql_adddatum((PLpgSQL_datum *) var);
  288. plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
  289. function->tg_name_varno = var->varno;
  290. /* ----------
  291.  * Add the variable tg_when
  292.  * ----------
  293.  */
  294. var = malloc(sizeof(PLpgSQL_var));
  295. memset(var, 0, sizeof(PLpgSQL_var));
  296. var->dtype = PLPGSQL_DTYPE_VAR;
  297. var->refname = strdup("tg_when");
  298. var->lineno = 0;
  299. plpgsql_parse_word("text");
  300. var->datatype = plpgsql_yylval.dtype;
  301. var->isconst = false;
  302. var->notnull = false;
  303. var->default_val = NULL;
  304. plpgsql_adddatum((PLpgSQL_datum *) var);
  305. plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
  306. function->tg_when_varno = var->varno;
  307. /* ----------
  308.  * Add the variable tg_level
  309.  * ----------
  310.  */
  311. var = malloc(sizeof(PLpgSQL_var));
  312. memset(var, 0, sizeof(PLpgSQL_var));
  313. var->dtype = PLPGSQL_DTYPE_VAR;
  314. var->refname = strdup("tg_level");
  315. var->lineno = 0;
  316. plpgsql_parse_word("text");
  317. var->datatype = plpgsql_yylval.dtype;
  318. var->isconst = false;
  319. var->notnull = false;
  320. var->default_val = NULL;
  321. plpgsql_adddatum((PLpgSQL_datum *) var);
  322. plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
  323. function->tg_level_varno = var->varno;
  324. /* ----------
  325.  * Add the variable tg_op
  326.  * ----------
  327.  */
  328. var = malloc(sizeof(PLpgSQL_var));
  329. memset(var, 0, sizeof(PLpgSQL_var));
  330. var->dtype = PLPGSQL_DTYPE_VAR;
  331. var->refname = strdup("tg_op");
  332. var->lineno = 0;
  333. plpgsql_parse_word("text");
  334. var->datatype = plpgsql_yylval.dtype;
  335. var->isconst = false;
  336. var->notnull = false;
  337. var->default_val = NULL;
  338. plpgsql_adddatum((PLpgSQL_datum *) var);
  339. plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
  340. function->tg_op_varno = var->varno;
  341. /* ----------
  342.  * Add the variable tg_relid
  343.  * ----------
  344.  */
  345. var = malloc(sizeof(PLpgSQL_var));
  346. memset(var, 0, sizeof(PLpgSQL_var));
  347. var->dtype = PLPGSQL_DTYPE_VAR;
  348. var->refname = strdup("tg_relid");
  349. var->lineno = 0;
  350. plpgsql_parse_word("oid");
  351. var->datatype = plpgsql_yylval.dtype;
  352. var->isconst = false;
  353. var->notnull = false;
  354. var->default_val = NULL;
  355. plpgsql_adddatum((PLpgSQL_datum *) var);
  356. plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
  357. function->tg_relid_varno = var->varno;
  358. /* ----------
  359.  * Add the variable tg_relname
  360.  * ----------
  361.  */
  362. var = malloc(sizeof(PLpgSQL_var));
  363. memset(var, 0, sizeof(PLpgSQL_var));
  364. var->dtype = PLPGSQL_DTYPE_VAR;
  365. var->refname = strdup("tg_relname");
  366. var->lineno = 0;
  367. plpgsql_parse_word("name");
  368. var->datatype = plpgsql_yylval.dtype;
  369. var->isconst = false;
  370. var->notnull = false;
  371. var->default_val = NULL;
  372. plpgsql_adddatum((PLpgSQL_datum *) var);
  373. plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
  374. function->tg_relname_varno = var->varno;
  375. /* ----------
  376.  * Add the variable tg_nargs
  377.  * ----------
  378.  */
  379. var = malloc(sizeof(PLpgSQL_var));
  380. memset(var, 0, sizeof(PLpgSQL_var));
  381. var->dtype = PLPGSQL_DTYPE_VAR;
  382. var->refname = strdup("tg_nargs");
  383. var->lineno = 0;
  384. plpgsql_parse_word("int4");
  385. var->datatype = plpgsql_yylval.dtype;
  386. var->isconst = false;
  387. var->notnull = false;
  388. var->default_val = NULL;
  389. plpgsql_adddatum((PLpgSQL_datum *) var);
  390. plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, var->refname);
  391. function->tg_nargs_varno = var->varno;
  392. break;
  393. default:
  394. elog(ERROR, "unknown function type %u in plpgsql_compile()",
  395.  functype);
  396. break;
  397. }
  398. /* ----------
  399.  * Create the magic found variable indicating if the
  400.  * last FOR or SELECT statement returned data
  401.  * ----------
  402.  */
  403. var = malloc(sizeof(PLpgSQL_var));
  404. memset(var, 0, sizeof(PLpgSQL_var));
  405. var->dtype = PLPGSQL_DTYPE_VAR;
  406. var->refname = strdup("found");
  407. var->lineno = 0;
  408. plpgsql_parse_word("bool");
  409. var->datatype = plpgsql_yylval.dtype;
  410. var->isconst = false;
  411. var->notnull = false;
  412. var->default_val = NULL;
  413. plpgsql_adddatum((PLpgSQL_datum *) var);
  414. plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, strdup("found"));
  415. function->found_varno = var->varno;
  416. /* ----------
  417.  * Forget about the above created variables
  418.  * ----------
  419.  */
  420. plpgsql_add_initdatums(NULL);
  421. /* ----------
  422.  * Now parse the functions text
  423.  * ----------
  424.  */
  425. parse_rc = plpgsql_yyparse();
  426. if (parse_rc != 0)
  427. {
  428. plpgsql_comperrinfo();
  429. elog(ERROR, "plpgsql: parser returned %d ???", parse_rc);
  430. }
  431. /* ----------
  432.  * If that was successful, complete the functions info.
  433.  * ----------
  434.  */
  435. function->fn_nargs = procStruct->pronargs;
  436. for (i = 0; i < function->fn_nargs; i++)
  437. function->fn_argvarnos[i] = arg_varnos[i];
  438. function->ndatums = plpgsql_nDatums;
  439. function->datums = malloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
  440. for (i = 0; i < plpgsql_nDatums; i++)
  441. function->datums[i] = plpgsql_Datums[i];
  442. function->action = plpgsql_yylval.program;
  443. /* ----------
  444.  * Finally return the compiled function
  445.  * ----------
  446.  */
  447. if (plpgsql_DumpExecTree)
  448. plpgsql_dumptree(function);
  449. return function;
  450. }
  451. /* ----------
  452.  * plpgsql_parse_word The scanner calls this to postparse
  453.  * any single word not found by a
  454.  * keyword rule.
  455.  * ----------
  456.  */
  457. int
  458. plpgsql_parse_word(char *word)
  459. {
  460. PLpgSQL_nsitem *nse;
  461. char    *cp;
  462. HeapTuple typeTup;
  463. Form_pg_type typeStruct;
  464. char    *typeXlated;
  465. /* ----------
  466.  * We do our lookups case insensitive
  467.  * ----------
  468.  */
  469. cp = plpgsql_tolower(word);
  470. /* ----------
  471.  * Special handling when compiling triggers
  472.  * ----------
  473.  */
  474. if (plpgsql_curr_compile->fn_functype == T_TRIGGER)
  475. {
  476. if (!strcmp(cp, "tg_argv"))
  477. {
  478. int save_spacescanned = plpgsql_SpaceScanned;
  479. PLpgSQL_trigarg *trigarg;
  480. trigarg = malloc(sizeof(PLpgSQL_trigarg));
  481. memset(trigarg, 0, sizeof(PLpgSQL_trigarg));
  482. trigarg->dtype = PLPGSQL_DTYPE_TRIGARG;
  483. if (plpgsql_yylex() != '[')
  484. plpgsql_yyerror("expected [");
  485. trigarg->argnum = plpgsql_read_expression(']', "]");
  486. plpgsql_adddatum((PLpgSQL_datum *) trigarg);
  487. plpgsql_yylval.trigarg = trigarg;
  488. plpgsql_SpaceScanned = save_spacescanned;
  489. return T_TGARGV;
  490. }
  491. }
  492. /* ----------
  493.  * Do a lookup on the compilers namestack
  494.  * ----------
  495.  */
  496. nse = plpgsql_ns_lookup(cp, NULL);
  497. if (nse != NULL)
  498. {
  499. pfree(cp);
  500. switch (nse->itemtype)
  501. {
  502. case PLPGSQL_NSTYPE_LABEL:
  503. return T_LABEL;
  504. case PLPGSQL_NSTYPE_VAR:
  505. plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[nse->itemno]);
  506. return T_VARIABLE;
  507. case PLPGSQL_NSTYPE_REC:
  508. plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[nse->itemno]);
  509. return T_RECORD;
  510. case PLPGSQL_NSTYPE_ROW:
  511. plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[nse->itemno]);
  512. return T_ROW;
  513. default:
  514. return T_ERROR;
  515. }
  516. }
  517. /* ----------
  518.  * Try to find a data type with that name, but ignore
  519.  * pg_type entries that are in fact class types.
  520.  * ----------
  521.  */
  522. typeXlated = xlateSqlType(cp);
  523. typeTup = SearchSysCacheTuple(TYPNAME,
  524.   PointerGetDatum(typeXlated), 0, 0, 0);
  525. if (HeapTupleIsValid(typeTup))
  526. {
  527. PLpgSQL_type *typ;
  528. typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
  529. if (typeStruct->typrelid != InvalidOid)
  530. {
  531. pfree(cp);
  532. return T_WORD;
  533. }
  534. typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
  535. typ->typname = strdup(nameout(&(typeStruct->typname)));
  536. typ->typoid = typeTup->t_data->t_oid;
  537. fmgr_info(typeStruct->typinput, &(typ->typinput));
  538. typ->typbyval = typeStruct->typbyval;
  539. typ->atttypmod = -1;
  540. plpgsql_yylval.dtype = typ;
  541. pfree(cp);
  542. return T_DTYPE;
  543. }
  544. /* ----------
  545.  * Nothing found - up to now it's a word without any
  546.  * special meaning for us.
  547.  * ----------
  548.  */
  549. pfree(cp);
  550. return T_WORD;
  551. }
  552. /* ----------
  553.  * plpgsql_parse_dblword Same lookup for two words
  554.  * separated by a dot.
  555.  * ----------
  556.  */
  557. int
  558. plpgsql_parse_dblword(char *string)
  559. {
  560. char    *word1;
  561. char    *word2;
  562. PLpgSQL_nsitem *ns;
  563. /* ----------
  564.  * Convert to lower case and separate the words
  565.  * ----------
  566.  */
  567. word1 = plpgsql_tolower(string);
  568. word2 = strchr(word1, '.');
  569. *word2++ = '';
  570. /* ----------
  571.  * Lookup the first word
  572.  * ----------
  573.  */
  574. ns = plpgsql_ns_lookup(word1, NULL);
  575. if (ns == NULL)
  576. {
  577. pfree(word1);
  578. return T_ERROR;
  579. }
  580. switch (ns->itemtype)
  581. {
  582. case PLPGSQL_NSTYPE_LABEL:
  583. /* ----------
  584.  * First word is a label, so second word could be
  585.  * a variable, record or row in that bodies namestack.
  586.  * Anything else could only be something in a query
  587.  * given to the SPI manager and T_ERROR will get eaten
  588.  * up by the collector routines.
  589.  * ----------
  590.  */
  591. ns = plpgsql_ns_lookup(word2, word1);
  592. if (ns == NULL)
  593. {
  594. pfree(word1);
  595. return T_ERROR;
  596. }
  597. switch (ns->itemtype)
  598. {
  599. case PLPGSQL_NSTYPE_VAR:
  600. plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[ns->itemno]);
  601. pfree(word1);
  602. return T_VARIABLE;
  603. case PLPGSQL_NSTYPE_REC:
  604. plpgsql_yylval.rec = (PLpgSQL_rec *) (plpgsql_Datums[ns->itemno]);
  605. pfree(word1);
  606. return T_RECORD;
  607. case PLPGSQL_NSTYPE_ROW:
  608. plpgsql_yylval.row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
  609. pfree(word1);
  610. return T_ROW;
  611. default:
  612. pfree(word1);
  613. return T_ERROR;
  614. }
  615. case PLPGSQL_NSTYPE_REC:
  616. {
  617. /* ----------
  618.  * First word is a record name, so second word
  619.  * must be a field in this record.
  620.  * ----------
  621.  */
  622. PLpgSQL_recfield *new;
  623. new = malloc(sizeof(PLpgSQL_recfield));
  624. new->dtype = PLPGSQL_DTYPE_RECFIELD;
  625. new->fieldname = strdup(word2);
  626. new->recno = ns->itemno;
  627. plpgsql_adddatum((PLpgSQL_datum *) new);
  628. pfree(word1);
  629. plpgsql_yylval.recfield = new;
  630. return T_RECFIELD;
  631. }
  632. case PLPGSQL_NSTYPE_ROW:
  633. {
  634. /* ----------
  635.  * First word is a row name, so second word must
  636.  * be a field in this row.
  637.  * ----------
  638.  */
  639. PLpgSQL_row *row;
  640. int i;
  641. row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
  642. for (i = 0; i < row->nfields; i++)
  643. {
  644. if (!strcmp(row->fieldnames[i], word2))
  645. {
  646. plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[row->varnos[i]]);
  647. pfree(word1);
  648. return T_VARIABLE;
  649. }
  650. }
  651. plpgsql_comperrinfo();
  652. elog(ERROR, "row %s doesn't have a field %s",
  653.  word1, word2);
  654. }
  655. default:
  656. break;
  657. }
  658. pfree(word1);
  659. return T_ERROR;
  660. }
  661. /* ----------
  662.  * plpgsql_parse_tripword Same lookup for three words
  663.  * separated by dots.
  664.  * ----------
  665.  */
  666. int
  667. plpgsql_parse_tripword(char *string)
  668. {
  669. char    *word1;
  670. char    *word2;
  671. char    *word3;
  672. PLpgSQL_nsitem *ns;
  673. /* ----------
  674.  * Convert to lower case and separate the words
  675.  * ----------
  676.  */
  677. word1 = plpgsql_tolower(string);
  678. word2 = strchr(word1, '.');
  679. *word2++ = '';
  680. word3 = strchr(word2, '.');
  681. *word3++ = '';
  682. /* ----------
  683.  * Lookup the first word - it must be a label
  684.  * ----------
  685.  */
  686. ns = plpgsql_ns_lookup(word1, NULL);
  687. if (ns == NULL)
  688. {
  689. pfree(word1);
  690. return T_ERROR;
  691. }
  692. if (ns->itemtype != PLPGSQL_NSTYPE_LABEL)
  693. {
  694. pfree(word1);
  695. return T_ERROR;
  696. }
  697. /* ----------
  698.  * First word is a label, so second word could be
  699.  * a record or row
  700.  * ----------
  701.  */
  702. ns = plpgsql_ns_lookup(word2, word1);
  703. if (ns == NULL)
  704. {
  705. pfree(word1);
  706. return T_ERROR;
  707. }
  708. switch (ns->itemtype)
  709. {
  710. case PLPGSQL_NSTYPE_REC:
  711. {
  712. /* ----------
  713.  * This word is a record name, so third word
  714.  * must be a field in this record.
  715.  * ----------
  716.  */
  717. PLpgSQL_recfield *new;
  718. new = malloc(sizeof(PLpgSQL_recfield));
  719. new->dtype = PLPGSQL_DTYPE_RECFIELD;
  720. new->fieldname = strdup(word3);
  721. new->recno = ns->itemno;
  722. plpgsql_adddatum((PLpgSQL_datum *) new);
  723. pfree(word1);
  724. plpgsql_yylval.recfield = new;
  725. return T_RECFIELD;
  726. }
  727. case PLPGSQL_NSTYPE_ROW:
  728. {
  729. /* ----------
  730.  * This word is a row name, so third word must
  731.  * be a field in this row.
  732.  * ----------
  733.  */
  734. PLpgSQL_row *row;
  735. int i;
  736. row = (PLpgSQL_row *) (plpgsql_Datums[ns->itemno]);
  737. for (i = 0; i < row->nfields; i++)
  738. {
  739. if (!strcmp(row->fieldnames[i], word3))
  740. {
  741. plpgsql_yylval.var = (PLpgSQL_var *) (plpgsql_Datums[row->varnos[i]]);
  742. pfree(word1);
  743. return T_VARIABLE;
  744. }
  745. }
  746. plpgsql_comperrinfo();
  747. elog(ERROR, "row %s.%s doesn't have a field %s",
  748.  word1, word2, word3);
  749. }
  750. default:
  751. break;
  752. }
  753. pfree(word1);
  754. return T_ERROR;
  755. }
  756. /* ----------
  757.  * plpgsql_parse_wordtype The scanner found word%TYPE. word can be
  758.  * a variable name or a basetype.
  759.  * ----------
  760.  */
  761. int
  762. plpgsql_parse_wordtype(char *word)
  763. {
  764. PLpgSQL_nsitem *nse;
  765. char    *cp;
  766. HeapTuple typeTup;
  767. Form_pg_type typeStruct;
  768. char    *typeXlated;
  769. bool old_nsstate;
  770. /* ----------
  771.  * We do our lookups case insensitive
  772.  * ----------
  773.  */
  774. cp = plpgsql_tolower(word);
  775. *(strchr(cp, '%')) = '';
  776. /* ----------
  777.  * Do a lookup on the compilers namestack.
  778.  * But ensure it moves up to the toplevel.
  779.  * ----------
  780.  */
  781. old_nsstate = plpgsql_ns_setlocal(false);
  782. nse = plpgsql_ns_lookup(cp, NULL);
  783. plpgsql_ns_setlocal(old_nsstate);
  784. if (nse != NULL)
  785. {
  786. pfree(cp);
  787. switch (nse->itemtype)
  788. {
  789. case PLPGSQL_NSTYPE_VAR:
  790. plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
  791. return T_DTYPE;
  792. default:
  793. return T_ERROR;
  794. }
  795. }
  796. /* ----------
  797.  * Word wasn't found on the namestack.
  798.  * Try to find a data type with that name, but ignore
  799.  * pg_type entries that are in fact class types.
  800.  * ----------
  801.  */
  802. typeXlated = xlateSqlType(cp);
  803. typeTup = SearchSysCacheTuple(TYPNAME,
  804.   PointerGetDatum(typeXlated), 0, 0, 0);
  805. if (HeapTupleIsValid(typeTup))
  806. {
  807. PLpgSQL_type *typ;
  808. typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
  809. if (typeStruct->typrelid != InvalidOid)
  810. {
  811. pfree(cp);
  812. return T_ERROR;
  813. }
  814. typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
  815. typ->typname = strdup(nameout(&(typeStruct->typname)));
  816. typ->typoid = typeTup->t_data->t_oid;
  817. fmgr_info(typeStruct->typinput, &(typ->typinput));
  818. typ->typbyval = typeStruct->typbyval;
  819. typ->atttypmod = -1;
  820. plpgsql_yylval.dtype = typ;
  821. pfree(cp);
  822. return T_DTYPE;
  823. }
  824. /* ----------
  825.  * Nothing found - up to now it's a word without any
  826.  * special meaning for us.
  827.  * ----------
  828.  */
  829. pfree(cp);
  830. return T_ERROR;
  831. }
  832. /* ----------
  833.  * plpgsql_parse_dblwordtype Same lookup for word.word%TYPE
  834.  * ----------
  835.  */
  836. int
  837. plpgsql_parse_dblwordtype(char *string)
  838. {
  839. char    *word1;
  840. char    *word2;
  841. PLpgSQL_nsitem *nse;
  842. bool old_nsstate;
  843. HeapTuple classtup;
  844. Form_pg_class classStruct;
  845. HeapTuple attrtup;
  846. Form_pg_attribute attrStruct;
  847. HeapTuple typetup;
  848. Form_pg_type typeStruct;
  849. PLpgSQL_type *typ;
  850. /* ----------
  851.  * Convert to lower case and separate the words
  852.  * ----------
  853.  */
  854. word1 = plpgsql_tolower(string);
  855. word2 = strchr(word1, '.');
  856. *word2++ = '';
  857. *(strchr(word2, '%')) = '';
  858. /* ----------
  859.  * Lookup the first word
  860.  * ----------
  861.  */
  862. nse = plpgsql_ns_lookup(word1, NULL);
  863. /* ----------
  864.  * If this is a label lookup the second word in that
  865.  * labels namestack level
  866.  * ----------
  867.  */
  868. if (nse != NULL)
  869. {
  870. if (nse->itemtype == PLPGSQL_NSTYPE_LABEL)
  871. {
  872. old_nsstate = plpgsql_ns_setlocal(false);
  873. nse = plpgsql_ns_lookup(word2, word1);
  874. plpgsql_ns_setlocal(old_nsstate);
  875. pfree(word1);
  876. if (nse != NULL)
  877. {
  878. switch (nse->itemtype)
  879. {
  880. case PLPGSQL_NSTYPE_VAR:
  881. plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype;
  882. return T_DTYPE;
  883. default:
  884. return T_ERROR;
  885. }
  886. }
  887. return T_ERROR;
  888. }
  889. pfree(word1);
  890. return T_ERROR;
  891. }
  892. /* ----------
  893.  * First word could also be a table name
  894.  * ----------
  895.  */
  896. classtup = SearchSysCacheTuple(RELNAME,
  897.    PointerGetDatum(word1), 0, 0, 0);
  898. if (!HeapTupleIsValid(classtup))
  899. {
  900. pfree(word1);
  901. return T_ERROR;
  902. }
  903. /* ----------
  904.  * It must be a (shared) relation class
  905.  * ----------
  906.  */
  907. classStruct = (Form_pg_class) GETSTRUCT(classtup);
  908. if (classStruct->relkind != 'r' && classStruct->relkind != 's')
  909. {
  910. pfree(word1);
  911. return T_ERROR;
  912. }
  913. /* ----------
  914.  * Fetch the named table field and it's type
  915.  * ----------
  916.  */
  917. attrtup = SearchSysCacheTuple(ATTNAME,
  918.    ObjectIdGetDatum(classtup->t_data->t_oid),
  919.   PointerGetDatum(word2), 0, 0);
  920. if (!HeapTupleIsValid(attrtup))
  921. {
  922. pfree(word1);
  923. return T_ERROR;
  924. }
  925. attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
  926. typetup = SearchSysCacheTuple(TYPOID,
  927. ObjectIdGetDatum(attrStruct->atttypid), 0, 0, 0);
  928. if (!HeapTupleIsValid(typetup))
  929. {
  930. plpgsql_comperrinfo();
  931. elog(ERROR, "cache lookup for type %u of %s.%s failed",
  932.  attrStruct->atttypid, word1, word2);
  933. }
  934. /* ----------
  935.  * Found that - build a compiler type struct and return it
  936.  * ----------
  937.  */
  938. typeStruct = (Form_pg_type) GETSTRUCT(typetup);
  939. typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
  940. typ->typname = strdup(nameout(&(typeStruct->typname)));
  941. typ->typoid = typetup->t_data->t_oid;
  942. fmgr_info(typeStruct->typinput, &(typ->typinput));
  943. typ->typbyval = typeStruct->typbyval;
  944. typ->atttypmod = attrStruct->atttypmod;
  945. plpgsql_yylval.dtype = typ;
  946. pfree(word1);
  947. return T_DTYPE;
  948. }
  949. /* ----------
  950.  * plpgsql_parse_wordrowtype Scanner found word%ROWTYPE.
  951.  * So word must be a table name.
  952.  * ----------
  953.  */
  954. int
  955. plpgsql_parse_wordrowtype(char *string)
  956. {
  957. HeapTuple classtup;
  958. Form_pg_class classStruct;
  959. HeapTuple typetup;
  960. Form_pg_type typeStruct;
  961. HeapTuple attrtup;
  962. Form_pg_attribute attrStruct;
  963. char    *word1;
  964. char    *cp;
  965. int i;
  966. PLpgSQL_row *row;
  967. PLpgSQL_var *var;
  968. /* ----------
  969.  * Get the word in lower case and fetch the pg_class tuple.
  970.  * ----------
  971.  */
  972. word1 = plpgsql_tolower(string);
  973. cp = strchr(word1, '%');
  974. *cp = '';
  975. classtup = SearchSysCacheTuple(RELNAME,
  976.    PointerGetDatum(word1), 0, 0, 0);
  977. if (!HeapTupleIsValid(classtup))
  978. {
  979. plpgsql_comperrinfo();
  980. elog(ERROR, "%s: no such class", word1);
  981. }
  982. classStruct = (Form_pg_class) GETSTRUCT(classtup);
  983. if (classStruct->relkind != 'r' && classStruct->relkind != 's')
  984. {
  985. plpgsql_comperrinfo();
  986. elog(ERROR, "%s isn't a table", word1);
  987. }
  988. /* ----------
  989.  * Fetch the tables pg_type tuple too
  990.  * ----------
  991.  */
  992. typetup = SearchSysCacheTuple(TYPNAME,
  993.   PointerGetDatum(word1), 0, 0, 0);
  994. if (!HeapTupleIsValid(typetup))
  995. {
  996. plpgsql_comperrinfo();
  997. elog(ERROR, "cache lookup for %s in pg_type failed", word1);
  998. }
  999. /* ----------
  1000.  * Create a row datum entry and all the required variables
  1001.  * that it will point to.
  1002.  * ----------
  1003.  */
  1004. row = malloc(sizeof(PLpgSQL_row));
  1005. memset(row, 0, sizeof(PLpgSQL_row));
  1006. row->dtype = PLPGSQL_DTYPE_ROW;
  1007. row->nfields = classStruct->relnatts;
  1008. row->rowtypeclass = typetup->t_data->t_oid;
  1009. row->fieldnames = malloc(sizeof(char *) * row->nfields);
  1010. row->varnos = malloc(sizeof(int) * row->nfields);
  1011. for (i = 0; i < row->nfields; i++)
  1012. {
  1013. /* ----------
  1014.  * Get the attribute and it's type
  1015.  * ----------
  1016.  */
  1017. attrtup = SearchSysCacheTuple(ATTNUM,
  1018.    ObjectIdGetDatum(classtup->t_data->t_oid),
  1019.   (Datum) (i + 1), 0, 0);
  1020. if (!HeapTupleIsValid(attrtup))
  1021. {
  1022. plpgsql_comperrinfo();
  1023. elog(ERROR, "cache lookup for attribute %d of class %s failed",
  1024.  i + 1, word1);
  1025. }
  1026. attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
  1027. typetup = SearchSysCacheTuple(TYPOID,
  1028. ObjectIdGetDatum(attrStruct->atttypid), 0, 0, 0);
  1029. if (!HeapTupleIsValid(typetup))
  1030. {
  1031. plpgsql_comperrinfo();
  1032. elog(ERROR, "cache lookup for type %u of %s.%s failed",
  1033.  attrStruct->atttypid, word1,
  1034.  nameout(&(attrStruct->attname)));
  1035. }
  1036. typeStruct = (Form_pg_type) GETSTRUCT(typetup);
  1037. cp = strdup(nameout(&(attrStruct->attname)));
  1038. /* ----------
  1039.  * Create the internal variable
  1040.  * We know if the table definitions contain a default value
  1041.  * or if the field is declared in the table as NOT NULL. But
  1042.  * it's possible to create a table field as NOT NULL without
  1043.  * a default value and that would lead to problems later when
  1044.  * initializing the variables due to entering a block at
  1045.  * execution time. Thus we ignore this information for now.
  1046.  * ----------
  1047.  */
  1048. var = malloc(sizeof(PLpgSQL_var));
  1049. var->dtype = PLPGSQL_DTYPE_VAR;
  1050. var->refname = malloc(strlen(word1) + strlen(cp) + 2);
  1051. strcpy(var->refname, word1);
  1052. strcat(var->refname, ".");
  1053. strcat(var->refname, cp);
  1054. var->datatype = malloc(sizeof(PLpgSQL_type));
  1055. var->datatype->typname = strdup(nameout(&(typeStruct->typname)));
  1056. var->datatype->typoid = typetup->t_data->t_oid;
  1057. fmgr_info(typeStruct->typinput, &(var->datatype->typinput));
  1058. var->datatype->typbyval = typeStruct->typbyval;
  1059. var->datatype->atttypmod = attrStruct->atttypmod;
  1060. var->isconst = false;
  1061. var->notnull = false;
  1062. var->default_val = NULL;
  1063. var->value = (Datum) 0;
  1064. var->isnull = true;
  1065. var->shouldfree = false;
  1066. plpgsql_adddatum((PLpgSQL_datum *) var);
  1067. /* ----------
  1068.  * Add the variable to the row.
  1069.  * ----------
  1070.  */
  1071. row->fieldnames[i] = cp;
  1072. row->varnos[i] = var->varno;
  1073. }
  1074. /* ----------
  1075.  * Return the complete row definition
  1076.  * ----------
  1077.  */
  1078. plpgsql_yylval.row = row;
  1079. return T_ROW;
  1080. }
  1081. /* ----------
  1082.  * plpgsql_adddatum Add a variable, record or row
  1083.  * to the compilers datum list.
  1084.  * ----------
  1085.  */
  1086. void
  1087. plpgsql_adddatum(PLpgSQL_datum * new)
  1088. {
  1089. if (plpgsql_nDatums == datums_alloc)
  1090. {
  1091. datums_alloc *= 2;
  1092. plpgsql_Datums = repalloc(plpgsql_Datums, sizeof(PLpgSQL_datum *) * datums_alloc);
  1093. }
  1094. new->dno = plpgsql_nDatums;
  1095. plpgsql_Datums[plpgsql_nDatums++] = new;
  1096. }
  1097. /* ----------
  1098.  * plpgsql_add_initdatums Put all datum entries created
  1099.  * since the last call into the
  1100.  * finishing code block so the
  1101.  * block knows which variables to
  1102.  * reinitialize when entered.
  1103.  * ----------
  1104.  */
  1105. int
  1106. plpgsql_add_initdatums(int **varnos)
  1107. {
  1108. int i;
  1109. int n = 0;
  1110. for (i = datums_last; i < plpgsql_nDatums; i++)
  1111. {
  1112. switch (plpgsql_Datums[i]->dtype)
  1113. {
  1114. case PLPGSQL_DTYPE_VAR:
  1115. n++;
  1116. break;
  1117. default:
  1118. break;
  1119. }
  1120. }
  1121. if (varnos != NULL)
  1122. {
  1123. *varnos = (int *) malloc(sizeof(int) * n);
  1124. n = 0;
  1125. for (i = datums_last; i < plpgsql_nDatums; i++)
  1126. {
  1127. switch (plpgsql_Datums[i]->dtype)
  1128. {
  1129. case PLPGSQL_DTYPE_VAR:
  1130. (*varnos)[n++] = plpgsql_Datums[i]->dno;
  1131. default:
  1132. break;
  1133. }
  1134. }
  1135. }
  1136. datums_last = plpgsql_nDatums;
  1137. return n;
  1138. }
  1139. /* ----------
  1140.  * plpgsql_comperrinfo Called before elog(ERROR, ...)
  1141.  * during compile.
  1142.  * ----------
  1143.  */
  1144. void
  1145. plpgsql_comperrinfo()
  1146. {
  1147. elog(NOTICE, "plpgsql: ERROR during compile of %s near line %d",
  1148.  plpgsql_error_funcname, plpgsql_error_lineno);
  1149. }
  1150. /* ---------
  1151.  * plpgsql_yyerror Handle parser error
  1152.  * ---------
  1153.  */
  1154. void
  1155. plpgsql_yyerror(const char *s)
  1156. {
  1157. plpgsql_error_lineno = plpgsql_yylineno;
  1158. plpgsql_comperrinfo();
  1159. elog(ERROR, "%s at or near "%s"", s, plpgsql_yytext);
  1160. }
  1161. /* ----------
  1162.  * xlateSqlType()
  1163.  * Convert alternate type names to internal Postgres types.
  1164.  *
  1165.  * Stolen from backend's main parser
  1166.  * ----------
  1167.  */
  1168. static char *
  1169. xlateSqlType(char *name)
  1170. {
  1171. if (!strcasecmp(name, "int")
  1172. || !strcasecmp(name, "integer"))
  1173. return "int4";
  1174. else if (!strcasecmp(name, "smallint"))
  1175. return "int2";
  1176. else if (!strcasecmp(name, "real")
  1177.  || !strcasecmp(name, "float"))
  1178. return "float8";
  1179. else if (!strcasecmp(name, "interval"))
  1180. return "timespan";
  1181. else if (!strcasecmp(name, "boolean"))
  1182. return "bool";
  1183. else
  1184. return name;
  1185. } /* xlateSqlType() */