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

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * define.c
  4.  *
  5.  *   These routines execute some of the CREATE statements.  In an earlier
  6.  *   version of Postgres, these were "define" statements.
  7.  *
  8.  * Copyright (c) 1994, Regents of the University of California
  9.  *
  10.  *
  11.  * IDENTIFICATION
  12.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/commands/define.c,v 1.29 1999/05/25 16:08:22 momjian Exp $
  13.  *
  14.  * DESCRIPTION
  15.  *   The "DefineFoo" routines take the parse tree and pick out the
  16.  *   appropriate arguments/flags, passing the results to the
  17.  *   corresponding "FooDefine" routines (in src/catalog) that do
  18.  *   the actual catalog-munging.  These routines also verify permission
  19.  *   of the user to execute the command.
  20.  *
  21.  * NOTES
  22.  *   These things must be defined and committed in the following order:
  23.  * "create function":
  24.  * input/output, recv/send procedures
  25.  * "create type":
  26.  * type
  27.  * "create operator":
  28.  * operators
  29.  *
  30.  * Most of the parse-tree manipulation routines are defined in
  31.  * commands/manip.c.
  32.  *
  33.  *-------------------------------------------------------------------------
  34.  */
  35. #include <stdio.h>
  36. #include <ctype.h>
  37. #include <string.h>
  38. #include <math.h>
  39. #include <postgres.h>
  40. #include <access/heapam.h>
  41. #include <catalog/catname.h>
  42. #include <catalog/pg_aggregate.h>
  43. #include <catalog/pg_operator.h>
  44. #include <catalog/pg_proc.h>
  45. #include <catalog/pg_type.h>
  46. #include <catalog/pg_language.h>
  47. #include <utils/syscache.h>
  48. #include <fmgr.h> /* for fmgr */
  49. #include <utils/builtins.h> /* prototype for textin() */
  50. #include <commands/defrem.h>
  51. #include <optimizer/xfunc.h>
  52. #include <tcop/dest.h>
  53. #include <catalog/pg_shadow.h>
  54. static char *defGetString(DefElem *def);
  55. static int defGetTypeLength(DefElem *def);
  56. #define DEFAULT_TYPDELIM ','
  57. static void
  58. case_translate_language_name(const char *input, char *output)
  59. {
  60. /*-------------------------------------------------------------------------
  61.   Translate the input language name to lower case, except if it's C,
  62.   translate to upper case.
  63. --------------------------------------------------------------------------*/
  64. int i;
  65. for (i = 0; i < NAMEDATALEN && input[i]; ++i)
  66. output[i] = tolower(input[i]);
  67. output[i] = '';
  68. if (strcmp(output, "c") == 0)
  69. output[0] = 'C';
  70. }
  71. static void
  72. compute_return_type(const Node *returnType,
  73. char **prorettype_p, bool *returnsSet_p)
  74. {
  75. /*---------------------------------------------------------------------------
  76.    Examine the "returns" clause returnType of the CREATE FUNCTION statement
  77.    and return information about it as **prorettype_p and **returnsSet.
  78. ----------------------------------------------------------------------------*/
  79. if (nodeTag(returnType) == T_TypeName)
  80. {
  81. /* a set of values */
  82. TypeName   *setType = (TypeName *) returnType;
  83. *prorettype_p = setType->name;
  84. *returnsSet_p = setType->setof;
  85. }
  86. else
  87. {
  88. /* singleton */
  89. *prorettype_p = strVal(returnType);
  90. *returnsSet_p = false;
  91. }
  92. }
  93. static void
  94. compute_full_attributes(const List *parameters, int32 *byte_pct_p,
  95. int32 *perbyte_cpu_p, int32 *percall_cpu_p,
  96. int32 *outin_ratio_p, bool *canCache_p)
  97. {
  98. /*--------------------------------------------------------------------------
  99.   Interpret the parameters *parameters and return their contents as
  100.   *byte_pct_p, etc.
  101.   These are the full parameters of a C or internal function.
  102. ---------------------------------------------------------------------------*/
  103. List    *pl;
  104. /* the defaults */
  105. *byte_pct_p = BYTE_PCT;
  106. *perbyte_cpu_p = PERBYTE_CPU;
  107. *percall_cpu_p = PERCALL_CPU;
  108. *outin_ratio_p = OUTIN_RATIO;
  109. foreach(pl, (List *) parameters)
  110. {
  111. ParamString *param = (ParamString *) lfirst(pl);
  112. if (strcasecmp(param->name, "iscachable") == 0)
  113. *canCache_p = true;
  114. else if (strcasecmp(param->name, "trusted") == 0)
  115. {
  116. /*
  117.  * we don't have untrusted functions any more. The 4.2
  118.  * implementation is lousy anyway so I took it out. -ay 10/94
  119.  */
  120. elog(ERROR, "untrusted function has been decommissioned.");
  121. }
  122. else if (strcasecmp(param->name, "byte_pct") == 0)
  123. {
  124. /*
  125.  * * handle expensive function parameters
  126.  */
  127. *byte_pct_p = atoi(param->val);
  128. }
  129. else if (strcasecmp(param->name, "perbyte_cpu") == 0)
  130. {
  131. if (sscanf(param->val, "%d", perbyte_cpu_p) == 0)
  132. {
  133. int count;
  134. char    *ptr;
  135. for (count = 0, ptr = param->val; *ptr != ''; ptr++)
  136. if (*ptr == '!')
  137. count++;
  138. *perbyte_cpu_p = (int) pow(10.0, (double) count);
  139. }
  140. }
  141. else if (strcasecmp(param->name, "percall_cpu") == 0)
  142. {
  143. if (sscanf(param->val, "%d", percall_cpu_p) == 0)
  144. {
  145. int count;
  146. char    *ptr;
  147. for (count = 0, ptr = param->val; *ptr != ''; ptr++)
  148. if (*ptr == '!')
  149. count++;
  150. *percall_cpu_p = (int) pow(10.0, (double) count);
  151. }
  152. }
  153. else if (strcasecmp(param->name, "outin_ratio") == 0)
  154. *outin_ratio_p = atoi(param->val);
  155. }
  156. }
  157. static void
  158. interpret_AS_clause(const char *languageName, const char *as,
  159. char **prosrc_str_p, char **probin_str_p)
  160. {
  161. if (strcmp(languageName, "C") == 0)
  162. {
  163. /* For "C" language, store the given string in probin */
  164. *prosrc_str_p = "-";
  165. *probin_str_p = (char *) as;
  166. }
  167. else
  168. {
  169. /* Everything else wants the given string in prosrc */
  170. *prosrc_str_p = (char *) as;
  171. *probin_str_p = "-";
  172. }
  173. }
  174. /*
  175.  * CreateFunction
  176.  *  Execute a CREATE FUNCTION utility statement.
  177.  *
  178.  */
  179. void
  180. CreateFunction(ProcedureStmt *stmt, CommandDest dest)
  181. {
  182. char    *probin_str;
  183. /* pathname of executable file that executes this function, if any */
  184. char    *prosrc_str;
  185. /* SQL that executes this function, if any */
  186. char    *prorettype;
  187. /* Type of return value (or member of set of values) from function */
  188. char languageName[NAMEDATALEN];
  189. /*
  190.  * name of language of function, with case adjusted: "C", "internal",
  191.  * or "SQL"
  192.  */
  193. /*
  194.  * The following are attributes of the function, as expressed in the
  195.  * CREATE FUNCTION statement, where applicable.
  196.  */
  197. int32 byte_pct,
  198. perbyte_cpu,
  199. percall_cpu,
  200. outin_ratio;
  201. bool canCache;
  202. bool returnsSet;
  203. bool lanisPL = false;
  204. /* The function returns a set of values, as opposed to a singleton. */
  205. case_translate_language_name(stmt->language, languageName);
  206. compute_return_type(stmt->returnType, &prorettype, &returnsSet);
  207. if (strcmp(languageName, "C") == 0 ||
  208. strcmp(languageName, "internal") == 0)
  209. {
  210. compute_full_attributes(stmt->withClause,
  211. &byte_pct, &perbyte_cpu, &percall_cpu,
  212. &outin_ratio, &canCache);
  213. }
  214. else if (strcmp(languageName, "sql") == 0)
  215. {
  216. /* query optimizer groks sql, these are meaningless */
  217. perbyte_cpu = percall_cpu = 0;
  218. byte_pct = outin_ratio = 100;
  219. canCache = false;
  220. }
  221. else
  222. {
  223. HeapTuple languageTuple;
  224. Form_pg_language languageStruct;
  225. /* Lookup the language in the system cache */
  226. languageTuple = SearchSysCacheTuple(LANNAME,
  227. PointerGetDatum(languageName),
  228. 0, 0, 0);
  229. if (!HeapTupleIsValid(languageTuple))
  230. {
  231. elog(ERROR,
  232.  "Unrecognized language specified in a CREATE FUNCTION: "
  233.  "'%s'.  Recognized languages are sql, C, internal "
  234.  "and the created procedural languages.",
  235.  languageName);
  236. }
  237. /* Check that this language is a PL */
  238. languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
  239. if (!(languageStruct->lanispl))
  240. {
  241. elog(ERROR,
  242.  "Language '%s' isn't defined as PL", languageName);
  243. }
  244. /*
  245.  * Functions in untrusted procedural languages are restricted to
  246.  * be defined by postgres superusers only
  247.  */
  248. if (languageStruct->lanpltrusted == false && !superuser())
  249. {
  250. elog(ERROR, "Only users with Postgres superuser privilege "
  251.  "are permitted to create a function in the '%s' "
  252.  "language.",
  253.  languageName);
  254. }
  255. lanisPL = true;
  256. /*
  257.  * These are meaningless
  258.  */
  259. perbyte_cpu = percall_cpu = 0;
  260. byte_pct = outin_ratio = 100;
  261. canCache = false;
  262. }
  263. interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str);
  264. if (strcmp(languageName, "sql") != 0 && lanisPL == false && !superuser())
  265. elog(ERROR,
  266.  "Only users with Postgres superuser privilege are permitted "
  267.  "to create a function "
  268.  "in the '%s' language.  Others may use the 'sql' language "
  269.  "or the created procedural languages.",
  270.  languageName);
  271. /* Above does not return. */
  272. else
  273. {
  274. /*
  275.  * And now that we have all the parameters, and know we're
  276.  * permitted to do so, go ahead and create the function.
  277.  */
  278. ProcedureCreate(stmt->funcname,
  279. returnsSet,
  280. prorettype,
  281. languageName,
  282. prosrc_str, /* converted to text later */
  283. probin_str, /* converted to text later */
  284. canCache,
  285. true, /* (obsolete "trusted") */
  286. byte_pct,
  287. perbyte_cpu,
  288. percall_cpu,
  289. outin_ratio,
  290. stmt->defArgs,
  291. dest);
  292. }
  293. }
  294. /* --------------------------------
  295.  * DefineOperator
  296.  *
  297.  * this function extracts all the information from the
  298.  * parameter list generated by the parser and then has
  299.  * OperatorCreate() do all the actual work.
  300.  *
  301.  * 'parameters' is a list of DefElem
  302.  * --------------------------------
  303.  */
  304. void
  305. DefineOperator(char *oprName,
  306.    List *parameters)
  307. {
  308. uint16 precedence = 0; /* operator precedence */
  309. bool canHash = false;/* operator hashes */
  310. bool isLeftAssociative = true; /* operator is left
  311.  * associative */
  312. char    *functionName = NULL; /* function for operator */
  313. char    *typeName1 = NULL; /* first type name */
  314. char    *typeName2 = NULL; /* second type name */
  315. char    *commutatorName = NULL; /* optional commutator operator
  316.  * name */
  317. char    *negatorName = NULL; /* optional negator operator name */
  318. char    *restrictionName = NULL; /* optional restrict. sel.
  319.  * procedure */
  320. char    *joinName = NULL;/* optional join sel. procedure name */
  321. char    *sortName1 = NULL; /* optional first sort operator */
  322. char    *sortName2 = NULL; /* optional second sort operator */
  323. List    *pl;
  324. /*
  325.  * loop over the definition list and extract the information we need.
  326.  */
  327. foreach(pl, parameters)
  328. {
  329. DefElem    *defel = (DefElem *) lfirst(pl);
  330. if (!strcasecmp(defel->defname, "leftarg"))
  331. {
  332. /* see gram.y, must be setof */
  333. if (nodeTag(defel->arg) == T_TypeName)
  334. elog(ERROR, "setof type not implemented for leftarg");
  335. if (nodeTag(defel->arg) == T_String)
  336. typeName1 = defGetString(defel);
  337. else
  338. elog(ERROR, "type for leftarg is malformed.");
  339. }
  340. else if (!strcasecmp(defel->defname, "rightarg"))
  341. {
  342. /* see gram.y, must be setof */
  343. if (nodeTag(defel->arg) == T_TypeName)
  344. elog(ERROR, "setof type not implemented for rightarg");
  345. if (nodeTag(defel->arg) == T_String)
  346. typeName2 = defGetString(defel);
  347. else
  348. elog(ERROR, "type for rightarg is malformed.");
  349. }
  350. else if (!strcasecmp(defel->defname, "procedure"))
  351. functionName = defGetString(defel);
  352. else if (!strcasecmp(defel->defname, "precedence"))
  353. {
  354. /* NOT IMPLEMENTED (never worked in v4.2) */
  355. elog(NOTICE, "CREATE OPERATOR: precedence not implemented");
  356. }
  357. else if (!strcasecmp(defel->defname, "associativity"))
  358. {
  359. /* NOT IMPLEMENTED (never worked in v4.2) */
  360. elog(NOTICE, "CREATE OPERATOR: associativity not implemented");
  361. }
  362. else if (!strcasecmp(defel->defname, "commutator"))
  363. commutatorName = defGetString(defel);
  364. else if (!strcasecmp(defel->defname, "negator"))
  365. negatorName = defGetString(defel);
  366. else if (!strcasecmp(defel->defname, "restrict"))
  367. restrictionName = defGetString(defel);
  368. else if (!strcasecmp(defel->defname, "join"))
  369. joinName = defGetString(defel);
  370. else if (!strcasecmp(defel->defname, "hashes"))
  371. canHash = TRUE;
  372. else if (!strcasecmp(defel->defname, "sort1"))
  373. {
  374. /* ----------------
  375.  * XXX ( ... [ , sort1 = oprname ] [ , sort2 = oprname ] ... )
  376.  * XXX is undocumented in the reference manual source as of
  377.  * 89/8/22.
  378.  * ----------------
  379.  */
  380. sortName1 = defGetString(defel);
  381. }
  382. else if (!strcasecmp(defel->defname, "sort2"))
  383. sortName2 = defGetString(defel);
  384. else
  385. {
  386. elog(NOTICE, "DefineOperator: attribute "%s" not recognized",
  387.  defel->defname);
  388. }
  389. }
  390. /*
  391.  * make sure we have our required definitions
  392.  */
  393. if (functionName == NULL)
  394. elog(ERROR, "Define: "procedure" unspecified");
  395. /* ----------------
  396.  * now have OperatorCreate do all the work..
  397.  * ----------------
  398.  */
  399. OperatorCreate(oprName, /* operator name */
  400.    typeName1, /* first type name */
  401.    typeName2, /* second type name */
  402.    functionName,/* function for operator */
  403.    precedence, /* operator precedence */
  404.    isLeftAssociative, /* operator is left associative */
  405.    commutatorName, /* optional commutator operator
  406.  * name */
  407.    negatorName, /* optional negator operator name */
  408.    restrictionName, /* optional restrict. sel.
  409.  * procedure */
  410.    joinName, /* optional join sel. procedure name */
  411.    canHash, /* operator hashes */
  412.    sortName1, /* optional first sort operator */
  413.    sortName2); /* optional second sort operator */
  414. }
  415. /* -------------------
  416.  * DefineAggregate
  417.  * ------------------
  418.  */
  419. void
  420. DefineAggregate(char *aggName, List *parameters)
  421. {
  422. char    *stepfunc1Name = NULL;
  423. char    *stepfunc2Name = NULL;
  424. char    *finalfuncName = NULL;
  425. char    *baseType = NULL;
  426. char    *stepfunc1Type = NULL;
  427. char    *stepfunc2Type = NULL;
  428. char    *init1 = NULL;
  429. char    *init2 = NULL;
  430. List    *pl;
  431. foreach(pl, parameters)
  432. {
  433. DefElem    *defel = (DefElem *) lfirst(pl);
  434. /*
  435.  * sfunc1
  436.  */
  437. if (!strcasecmp(defel->defname, "sfunc1"))
  438. stepfunc1Name = defGetString(defel);
  439. else if (!strcasecmp(defel->defname, "basetype"))
  440. baseType = defGetString(defel);
  441. else if (!strcasecmp(defel->defname, "stype1"))
  442. {
  443. stepfunc1Type = defGetString(defel);
  444. /*
  445.  * sfunc2
  446.  */
  447. }
  448. else if (!strcasecmp(defel->defname, "sfunc2"))
  449. stepfunc2Name = defGetString(defel);
  450. else if (!strcasecmp(defel->defname, "stype2"))
  451. {
  452. stepfunc2Type = defGetString(defel);
  453. /*
  454.  * final
  455.  */
  456. }
  457. else if (!strcasecmp(defel->defname, "finalfunc"))
  458. {
  459. finalfuncName = defGetString(defel);
  460. /*
  461.  * initial conditions
  462.  */
  463. }
  464. else if (!strcasecmp(defel->defname, "initcond1"))
  465. init1 = defGetString(defel);
  466. else if (!strcasecmp(defel->defname, "initcond2"))
  467. init2 = defGetString(defel);
  468. else
  469. {
  470. elog(NOTICE, "DefineAggregate: attribute "%s" not recognized",
  471.  defel->defname);
  472. }
  473. }
  474. /*
  475.  * make sure we have our required definitions
  476.  */
  477. if (baseType == NULL)
  478. elog(ERROR, "Define: "basetype" unspecified");
  479. if (stepfunc1Name != NULL)
  480. {
  481. if (stepfunc1Type == NULL)
  482. elog(ERROR, "Define: "stype1" unspecified");
  483. }
  484. if (stepfunc2Name != NULL)
  485. {
  486. if (stepfunc2Type == NULL)
  487. elog(ERROR, "Define: "stype2" unspecified");
  488. }
  489. /*
  490.  * Most of the argument-checking is done inside of AggregateCreate
  491.  */
  492. AggregateCreate(aggName, /* aggregate name */
  493. stepfunc1Name, /* first step function name */
  494. stepfunc2Name, /* second step function name */
  495. finalfuncName, /* final function name */
  496. baseType, /* type of object being aggregated */
  497. stepfunc1Type, /* return type of first function */
  498. stepfunc2Type, /* return type of second function */
  499. init1, /* first initial condition */
  500. init2); /* second initial condition */
  501. /* XXX free palloc'd memory */
  502. }
  503. /*
  504.  * DefineType
  505.  * Registers a new type.
  506.  *
  507.  */
  508. void
  509. DefineType(char *typeName, List *parameters)
  510. {
  511. int16 internalLength = 0; /* int2 */
  512. int16 externalLength = 0; /* int2 */
  513. char    *elemName = NULL;
  514. char    *inputName = NULL;
  515. char    *outputName = NULL;
  516. char    *sendName = NULL;
  517. char    *receiveName = NULL;
  518. char    *defaultValue = NULL; /* Datum */
  519. bool byValue = false;
  520. char delimiter = DEFAULT_TYPDELIM;
  521. char    *shadow_type;
  522. List    *pl;
  523. char alignment = 'i';/* default alignment */
  524. /*
  525.  * Type names can only be 15 characters long, so that the shadow type
  526.  * can be created using the 16th character as necessary.
  527.  */
  528. if (strlen(typeName) >= (NAMEDATALEN - 1))
  529. {
  530. elog(ERROR, "DefineType: type names must be %d characters or less",
  531.  NAMEDATALEN - 1);
  532. }
  533. foreach(pl, parameters)
  534. {
  535. DefElem    *defel = (DefElem *) lfirst(pl);
  536. if (!strcasecmp(defel->defname, "internallength"))
  537. internalLength = defGetTypeLength(defel);
  538. else if (!strcasecmp(defel->defname, "externallength"))
  539. externalLength = defGetTypeLength(defel);
  540. else if (!strcasecmp(defel->defname, "input"))
  541. inputName = defGetString(defel);
  542. else if (!strcasecmp(defel->defname, "output"))
  543. outputName = defGetString(defel);
  544. else if (!strcasecmp(defel->defname, "send"))
  545. sendName = defGetString(defel);
  546. else if (!strcasecmp(defel->defname, "delimiter"))
  547. {
  548. char    *p = defGetString(defel);
  549. delimiter = p[0];
  550. }
  551. else if (!strcasecmp(defel->defname, "receive"))
  552. receiveName = defGetString(defel);
  553. else if (!strcasecmp(defel->defname, "element"))
  554. elemName = defGetString(defel);
  555. else if (!strcasecmp(defel->defname, "default"))
  556. defaultValue = defGetString(defel);
  557. else if (!strcasecmp(defel->defname, "passedbyvalue"))
  558. byValue = true;
  559. else if (!strcasecmp(defel->defname, "alignment"))
  560. {
  561. char    *a = defGetString(defel);
  562. if (!strcasecmp(a, "double"))
  563. alignment = 'd';
  564. else if (!strcasecmp(a, "int"))
  565. alignment = 'i';
  566. else
  567. {
  568. elog(ERROR, "DefineType: "%s" alignment  not recognized",
  569.  a);
  570. }
  571. }
  572. else
  573. {
  574. elog(NOTICE, "DefineType: attribute "%s" not recognized",
  575.  defel->defname);
  576. }
  577. }
  578. /*
  579.  * make sure we have our required definitions
  580.  */
  581. if (inputName == NULL)
  582. elog(ERROR, "Define: "input" unspecified");
  583. if (outputName == NULL)
  584. elog(ERROR, "Define: "output" unspecified");
  585. /* ----------------
  586.  * now have TypeCreate do all the real work.
  587.  * ----------------
  588.  */
  589. TypeCreate(typeName, /* type name */
  590.    InvalidOid, /* relation oid (n/a here) */
  591.    internalLength, /* internal size */
  592.    externalLength, /* external size */
  593.    'b', /* type-type (base type) */
  594.    delimiter, /* array element delimiter */
  595.    inputName, /* input procedure */
  596.    outputName, /* output procedure */
  597.    receiveName, /* receive procedure */
  598.    sendName, /* send procedure */
  599.    elemName, /* element type name */
  600.    defaultValue, /* default type value */
  601.    byValue, /* passed by value */
  602.    alignment);
  603. /* ----------------
  604.  * When we create a true type (as opposed to a complex type)
  605.  * we need to have an shadow array entry for it in pg_type as well.
  606.  * ----------------
  607.  */
  608. shadow_type = makeArrayTypeName(typeName);
  609. TypeCreate(shadow_type, /* type name */
  610.    InvalidOid, /* relation oid (n/a here) */
  611.    -1, /* internal size */
  612.    -1, /* external size */
  613.    'b', /* type-type (base type) */
  614.    DEFAULT_TYPDELIM,/* array element delimiter */
  615.    "array_in", /* input procedure */
  616.    "array_out", /* output procedure */
  617.    "array_in", /* receive procedure */
  618.    "array_out", /* send procedure */
  619.    typeName, /* element type name */
  620.    defaultValue, /* default type value */
  621.    false, /* never passed by value */
  622.    alignment);
  623. pfree(shadow_type);
  624. }
  625. static char *
  626. defGetString(DefElem *def)
  627. {
  628. if (nodeTag(def->arg) != T_String)
  629. elog(ERROR, "Define: "%s" = what?", def->defname);
  630. return strVal(def->arg);
  631. }
  632. static int
  633. defGetTypeLength(DefElem *def)
  634. {
  635. if (nodeTag(def->arg) == T_Integer)
  636. return intVal(def->arg);
  637. else if (nodeTag(def->arg) == T_String &&
  638.  !strcasecmp(strVal(def->arg), "variable"))
  639. return -1; /* variable length */
  640. elog(ERROR, "Define: "%s" = what?", def->defname);
  641. return -1;
  642. }