diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index 9f6b0abc8d5..1409c1d2881 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -1,31 +1,34 @@ /*------------------------------------------------------------------------- * * define.c-- - * POSTGRES "define" utility code. + * + * These routines execute some of the CREATE statements. In an earlier + * version of Postgres, these were "define" statements. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.2 1996/10/23 07:40:01 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.3 1996/10/31 09:07:41 bryanh Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the * appropriate arguments/flags, passing the results to the * corresponding "FooDefine" routines (in src/catalog) that do - * the actual catalog-munging. + * the actual catalog-munging. These routines also verify permission + * of the user to execute the command. * * NOTES * These things must be defined and committed in the following order: - * "define function": - * input/output, recv/send procedures - * "define type": - * type - * "define operator": - * operators + * "create function": + * input/output, recv/send procedures + * "create type": + * type + * "create operator": + * operators * - * Most of the parse-tree manipulation routines are defined in - * commands/manip.c. + * Most of the parse-tree manipulation routines are defined in + * commands/manip.c. * *------------------------------------------------------------------------- */ @@ -33,298 +36,358 @@ #include #include -#include "postgres.h" +#include -#include "access/heapam.h" -#include "access/htup.h" -#include "utils/tqual.h" -#include "catalog/catname.h" -#include "catalog/pg_aggregate.h" -#include "catalog/pg_proc.h" -#include "catalog/pg_type.h" -#include "catalog/pg_operator.h" -#include "utils/syscache.h" -#include "nodes/pg_list.h" -#include "nodes/parsenodes.h" -#include "fmgr.h" /* for fmgr */ +#include +#include +#include +#include +#include +#include +#include +#include +#include /* superuser() uses this */ +#include +#include +#include +#include /* for fmgr */ -#include "utils/builtins.h" /* prototype for textin() */ +#include /* prototype for textin() */ -#include "utils/elog.h" -#include "utils/palloc.h" -#include "commands/defrem.h" -#include "optimizer/xfunc.h" -#include "tcop/dest.h" +#include +#include +#include +#include +#include static char *defGetString(DefElem *def); static int defGetTypeLength(DefElem *def); -#define DEFAULT_TYPDELIM ',' +#define DEFAULT_TYPDELIM ',' + + +bool +superuser(void) { +/*-------------------------------------------------------------------------- + The Postgres user running this command has Postgres superuser + privileges. +--------------------------------------------------------------------------*/ + HeapTuple utup; + char *userName; + + userName = GetPgUserName(); + utup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName), + 0,0,0); + Assert(utup != NULL); + return ((Form_pg_user)GETSTRUCT(utup))->usesuper; +} + + + +void +case_translate_language_name(const char *input, char *output) { +/*------------------------------------------------------------------------- + Translate the input language name to lower case, except if it's C, + translate to upper case. +--------------------------------------------------------------------------*/ + int i; + + for (i = 0; i < NAMEDATALEN && input[i] != '\0'; ++i) + output[i] = tolower(input[i]); + + output[i] = '\0'; + + if (strcmp(output, "c") == 0) output[0] = 'C'; +} + + + +void +compute_return_type(const Node *returnType, + char **prorettype_p, bool *returnsSet_p) { +/*--------------------------------------------------------------------------- + Examine the "returns" clause returnType of the CREATE FUNCTION statement + and return information about it as **prorettype_p and **returnsSet. +----------------------------------------------------------------------------*/ + if (nodeTag(returnType) == T_TypeName) { + /* a set of values */ + TypeName *setType = (TypeName *)returnType; + *prorettype_p = setType->name, + *returnsSet_p = true; + }else { + /* singleton */ + *prorettype_p = strVal(returnType); + *returnsSet_p = false; + } +} + + + +void +compute_full_attributes(const List *parameters, int32 *byte_pct_p, + int32 *perbyte_cpu_p, int32 *percall_cpu_p, + int32 *outin_ratio_p, bool *canCache_p) { +/*-------------------------------------------------------------------------- + Interpret the parameters *parameters and return their contents as + *byte_pct_p, etc. + + These are the full parameters of a C or internal function. +---------------------------------------------------------------------------*/ + List *pl; + + /* the defaults */ + *byte_pct_p = BYTE_PCT; + *perbyte_cpu_p = PERBYTE_CPU; + *percall_cpu_p = PERCALL_CPU; + *outin_ratio_p = OUTIN_RATIO; + + foreach(pl, (List *)parameters) { + int count; + char *ptr; + ParamString *param = (ParamString*)lfirst(pl); + + if (strcasecmp(param->name, "iscachable") == 0) { + *canCache_p = true; + } else if (strcasecmp(param->name, "trusted") == 0) { + /* + * we don't have untrusted functions any more. The 4.2 + * implementation is lousy anyway so I took it out. + * -ay 10/94 + */ + elog(WARN, "untrusted function has been decommissioned."); + } else if (strcasecmp(param->name, "byte_pct") == 0) { + /* + ** handle expensive function parameters + */ + *byte_pct_p = atoi(param->val); + } else if (strcasecmp(param->name, "perbyte_cpu") == 0) { + if (sscanf(param->val, "%d", perbyte_cpu_p) == 0) { + for (count = 0, ptr = param->val; *ptr != '\0'; ptr++) + if (*ptr == '!') count++; + } + *perbyte_cpu_p = (int) pow(10.0, (double) count); + } else if (strcasecmp(param->name, "percall_cpu") == 0) { + if (sscanf(param->val, "%d", percall_cpu_p) == 0) { + for (count = 0, ptr = param->val; *ptr != '\0'; ptr++) + if (*ptr == '!') count++; + *percall_cpu_p = (int) pow(10.0, (double) count); + } + } else if (strcasecmp(param->name, "outin_ratio") == 0) { + *outin_ratio_p = atoi(param->val); + } + } +} + + + +void +interpret_AS_clause(const char languageName[], const char as[], + char **prosrc_str_p, char **probin_str_p) { + + if ( strcmp(languageName, "C") == 0 || + strcmp(languageName, "internal") == 0 ) { + *prosrc_str_p = "-"; + *probin_str_p = (char *)as; + } else { + *prosrc_str_p = (char *)as; + *probin_str_p = "-"; + } +} + + /* - * DefineFunction -- - * Registers a new function. + * CreateFunction -- + * Execute a CREATE FUNCTION utility statement. * */ void -DefineFunction(ProcedureStmt *stmt, CommandDest dest) +CreateFunction(ProcedureStmt *stmt, CommandDest dest) { - List *parameters = stmt->withClause; - char *proname = stmt->funcname; - char* probin_str; - char* prosrc_str; - char *prorettype; - char *languageName; - bool canCache = FALSE; - List *argList; - int32 byte_pct = 100, perbyte_cpu, percall_cpu, outin_ratio = 100; - bool returnsSet; - int i; - - /* ---------------- - * figure out the language and convert it to lowercase. - * ---------------- - */ - languageName = stmt->language; - for (i = 0; i < NAMEDATALEN && languageName[i]; ++i) { - languageName[i] = tolower(languageName[i]); - } - - /* ---------------- - * handle "returntype = X". The function could return a singleton - * value or a set of values. Figure out which. - * ---------------- - */ - if (nodeTag(stmt->returnType)==T_TypeName) { - TypeName *setType = (TypeName *)stmt->returnType; - /* a set of values */ - prorettype = setType->name, - returnsSet = true; - }else { - /* singleton */ - prorettype = strVal(stmt->returnType); - returnsSet = false; - } - - /* Next attributes are only defined for C functions */ - if ( strcmp(languageName, "c") == 0 || - strcmp(languageName, "internal") == 0 ) { - List *pl; + char *probin_str; + /* pathname of executable file that executes this function, if any */ + char *prosrc_str; + /* SQL that executes this function, if any */ + char *prorettype; + /* Type of return value (or member of set of values) from function */ + char languageName[NAMEDATALEN+1]; + /* name of language of function, with case adjusted: + "C", "internal", or "SQL" + */ + /* The following are attributes of the function, as expressed in the + CREATE FUNCTION statement, where applicable. + */ + int32 byte_pct, perbyte_cpu, percall_cpu, outin_ratio; + bool canCache; + bool returnsSet; + /* The function returns a set of values, as opposed to a singleton. */ - /* the defaults */ - byte_pct = BYTE_PCT; - perbyte_cpu = PERBYTE_CPU; - percall_cpu = PERCALL_CPU; - outin_ratio = OUTIN_RATIO; - foreach(pl, parameters) { - int count; - char *ptr; - ParamString *param = (ParamString*)lfirst(pl); + case_translate_language_name(stmt->language, languageName); - if (!strcasecmp(param->name, "isacachable")) { - /* ---------------- - * handle "[ iscachable ]": figure out if Postquel functions - * are cacheable automagically? - * ---------------- - */ - canCache = TRUE; - }else if (!strcasecmp(param->name, "trusted")) { - /* - * we don't have untrusted functions any more. The 4.2 - * implementation is lousy anyway so I took it out. - * -ay 10/94 - */ - elog(WARN, "untrusted function has been decommissioned."); - }else if (!strcasecmp(param->name, "byte_pct")) { - /* - ** handle expensive function parameters - */ - byte_pct = atoi(param->val); - }else if (!strcasecmp(param->name, "perbyte_cpu")) { - if (!sscanf(param->val, "%d", &perbyte_cpu)) { - for (count = 0, ptr = param->val; *ptr != '\0'; ptr++) { - if (*ptr == '!') { - count++; - } - } - perbyte_cpu = (int) pow(10.0, (double) count); - } - }else if (!strcasecmp(param->name, "percall_cpu")) { - if (!sscanf(param->val, "%d", &percall_cpu)) { - for (count = 0, ptr = param->val; *ptr != '\0'; ptr++) { - if (*ptr == '!') { - count++; - } - } - percall_cpu = (int) pow(10.0, (double) count); - } - }else if (!strcasecmp(param->name, "outin_ratio")) { - outin_ratio = atoi(param->val); - } - } - } else if (!strcmp(languageName, "sql")) { - /* query optimizer groks sql, these are meaningless */ - perbyte_cpu = percall_cpu = 0; + compute_return_type(stmt->returnType, &prorettype, &returnsSet); + + if ( strcmp(languageName, "C") == 0 || + strcmp(languageName, "internal") == 0 ) { + compute_full_attributes(stmt->withClause, + &byte_pct, &perbyte_cpu, &percall_cpu, + &outin_ratio, &canCache); + } else if (strcmp(languageName, "sql") == 0) { + /* query optimizer groks sql, these are meaningless */ + perbyte_cpu = percall_cpu = 0; + byte_pct = outin_ratio = 100; + canCache = false; } else { - elog(WARN, "DefineFunction: language '%s' is not supported", - languageName); + elog(WARN, + "Unrecognized language specified in a CREATE FUNCTION: " + "'%s'. Recognized languages are sql, C, and internal.", + languageName); } - - /* ---------------- - * handle "[ arg is (...) ]" - * XXX fix optional arg handling below - * ---------------- - */ - argList = stmt->defArgs; - - if ( strcmp(languageName, "c") == 0 || - strcmp(languageName, "internal") == 0 ) { - prosrc_str = "-"; - probin_str = stmt->as; - } else { - prosrc_str = stmt->as; - probin_str = "-"; - } - - /* C is stored uppercase in pg_language */ - if (!strcmp(languageName, "c")) { - languageName[0] = 'C'; - } - - /* ---------------- - * now have ProcedureDefine do all the work.. - * ---------------- - */ - ProcedureCreate(proname, - returnsSet, - prorettype, - languageName, - prosrc_str, /* converted to text later */ - probin_str, /* converted to text later */ - canCache, - TRUE, - byte_pct, - perbyte_cpu, - percall_cpu, - outin_ratio, - argList, - dest); - + + interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str); + + if (strcmp(languageName, "sql") != 0 && !superuser()) + elog(WARN, + "Only users with Postgres superuser privilege are permitted " + "to create a function " + "in the '%s' language. Others may use the 'sql' language.", + languageName); + /* Above does not return. */ + else { + /* And now that we have all the parameters, and know we're permitted + to do so, go ahead and create the function. + */ + ProcedureCreate(stmt->funcname, + returnsSet, + prorettype, + languageName, + prosrc_str, /* converted to text later */ + probin_str, /* converted to text later */ + canCache, + true, /* (obsolete "trusted") */ + byte_pct, + perbyte_cpu, + percall_cpu, + outin_ratio, + stmt->defArgs, + dest); + } } + + /* -------------------------------- * DefineOperator-- * - * this function extracts all the information from the - * parameter list generated by the parser and then has - * OperatorCreate() do all the actual work. + * this function extracts all the information from the + * parameter list generated by the parser and then has + * OperatorCreate() do all the actual work. * * 'parameters' is a list of DefElem * -------------------------------- */ void -DefineOperator(char *oprName, - List *parameters) +DefineOperator(char *oprName, + List *parameters) { - uint16 precedence=0; /* operator precedence */ - bool canHash=false; /* operator hashes */ - bool isLeftAssociative=true; /* operator is left associative */ - char *functionName=NULL; /* function for operator */ - char *typeName1=NULL; /* first type name */ - char *typeName2=NULL; /* second type name */ - char *commutatorName=NULL; /* optional commutator operator name */ - char *negatorName=NULL; /* optional negator operator name */ - char *restrictionName=NULL; /* optional restrict. sel. procedure */ - char *joinName=NULL; /* optional join sel. procedure name */ - char *sortName1=NULL; /* optional first sort operator */ - char *sortName2=NULL; /* optional second sort operator */ - List *pl; + uint16 precedence=0; /* operator precedence */ + bool canHash=false; /* operator hashes */ + bool isLeftAssociative=true; /* operator is left associative */ + char *functionName=NULL; /* function for operator */ + char *typeName1=NULL; /* first type name */ + char *typeName2=NULL; /* second type name */ + char *commutatorName=NULL; /* optional commutator operator name */ + char *negatorName=NULL; /* optional negator operator name */ + char *restrictionName=NULL; /* optional restrict. sel. procedure */ + char *joinName=NULL; /* optional join sel. procedure name */ + char *sortName1=NULL; /* optional first sort operator */ + char *sortName2=NULL; /* optional second sort operator */ + List *pl; /* * loop over the definition list and extract the information we need. */ foreach (pl, parameters) { - DefElem *defel = (DefElem *)lfirst(pl); + DefElem *defel = (DefElem *)lfirst(pl); - if (!strcasecmp(defel->defname, "leftarg")) { - /* see gram.y, must be setof */ - if (nodeTag(defel->arg)==T_TypeName) - elog(WARN, "setof type not implemented for leftarg"); + if (!strcasecmp(defel->defname, "leftarg")) { + /* see gram.y, must be setof */ + if (nodeTag(defel->arg)==T_TypeName) + elog(WARN, "setof type not implemented for leftarg"); - if (nodeTag(defel->arg)==T_String) { - typeName1 = defGetString(defel); - }else { - elog(WARN, "type for leftarg is malformed."); - } - } else if (!strcasecmp(defel->defname, "rightarg")) { - /* see gram.y, must be setof */ - if (nodeTag(defel->arg)==T_TypeName) - elog(WARN, "setof type not implemented for rightarg"); + if (nodeTag(defel->arg)==T_String) { + typeName1 = defGetString(defel); + }else { + elog(WARN, "type for leftarg is malformed."); + } + } else if (!strcasecmp(defel->defname, "rightarg")) { + /* see gram.y, must be setof */ + if (nodeTag(defel->arg)==T_TypeName) + elog(WARN, "setof type not implemented for rightarg"); - if (nodeTag(defel->arg)==T_String) { - typeName2 = defGetString(defel); - }else { - elog(WARN, "type for rightarg is malformed."); - } - } else if (!strcasecmp(defel->defname, "procedure")) { - functionName = defGetString(defel); - } else if (!strcasecmp(defel->defname, "precedence")) { - /* NOT IMPLEMENTED (never worked in v4.2) */ - elog(NOTICE, "CREATE OPERATOR: precedence not implemented"); - } else if (!strcasecmp(defel->defname, "associativity")) { - /* NOT IMPLEMENTED (never worked in v4.2) */ - elog(NOTICE, "CREATE OPERATOR: associativity not implemented"); - } else if (!strcasecmp(defel->defname, "commutator")) { - commutatorName = defGetString(defel); - } else if (!strcasecmp(defel->defname, "negator")) { - negatorName = defGetString(defel); - } else if (!strcasecmp(defel->defname, "restrict")) { - restrictionName = defGetString(defel); - } else if (!strcasecmp(defel->defname, "join")) { - joinName = defGetString(defel); - } else if (!strcasecmp(defel->defname, "hashes")) { - canHash = TRUE; - } else if (!strcasecmp(defel->defname, "sort1")) { - /* ---------------- - * XXX ( ... [ , sort1 = oprname ] [ , sort2 = oprname ] ... ) - * XXX is undocumented in the reference manual source as of - * 89/8/22. - * ---------------- - */ - sortName1 = defGetString(defel); - } else if (!strcasecmp(defel->defname, "sort2")) { - sortName2 = defGetString(defel); - } else { - elog(NOTICE, "DefineOperator: attribute \"%s\" not recognized", - defel->defname); - } + if (nodeTag(defel->arg)==T_String) { + typeName2 = defGetString(defel); + }else { + elog(WARN, "type for rightarg is malformed."); + } + } else if (!strcasecmp(defel->defname, "procedure")) { + functionName = defGetString(defel); + } else if (!strcasecmp(defel->defname, "precedence")) { + /* NOT IMPLEMENTED (never worked in v4.2) */ + elog(NOTICE, "CREATE OPERATOR: precedence not implemented"); + } else if (!strcasecmp(defel->defname, "associativity")) { + /* NOT IMPLEMENTED (never worked in v4.2) */ + elog(NOTICE, "CREATE OPERATOR: associativity not implemented"); + } else if (!strcasecmp(defel->defname, "commutator")) { + commutatorName = defGetString(defel); + } else if (!strcasecmp(defel->defname, "negator")) { + negatorName = defGetString(defel); + } else if (!strcasecmp(defel->defname, "restrict")) { + restrictionName = defGetString(defel); + } else if (!strcasecmp(defel->defname, "join")) { + joinName = defGetString(defel); + } else if (!strcasecmp(defel->defname, "hashes")) { + canHash = TRUE; + } else if (!strcasecmp(defel->defname, "sort1")) { + /* ---------------- + * XXX ( ... [ , sort1 = oprname ] [ , sort2 = oprname ] ... ) + * XXX is undocumented in the reference manual source as of + * 89/8/22. + * ---------------- + */ + sortName1 = defGetString(defel); + } else if (!strcasecmp(defel->defname, "sort2")) { + sortName2 = defGetString(defel); + } else { + elog(NOTICE, "DefineOperator: attribute \"%s\" not recognized", + defel->defname); + } } /* * make sure we have our required definitions */ if (functionName==NULL) { - elog(WARN, "Define: \"procedure\" unspecified"); + elog(WARN, "Define: \"procedure\" unspecified"); } /* ---------------- - * now have OperatorCreate do all the work.. + * now have OperatorCreate do all the work.. * ---------------- */ - OperatorCreate(oprName, /* operator name */ - typeName1, /* first type name */ - typeName2, /* second type name */ - functionName, /* function for operator */ - precedence, /* operator precedence */ - isLeftAssociative, /* operator is left associative */ - commutatorName, /* optional commutator operator name */ - negatorName, /* optional negator operator name */ - restrictionName, /* optional restrict. sel. procedure */ - joinName, /* optional join sel. procedure name */ - canHash, /* operator hashes */ - sortName1, /* optional first sort operator */ - sortName2); /* optional second sort operator */ + OperatorCreate(oprName, /* operator name */ + typeName1, /* first type name */ + typeName2, /* second type name */ + functionName, /* function for operator */ + precedence, /* operator precedence */ + isLeftAssociative, /* operator is left associative */ + commutatorName, /* optional commutator operator name */ + negatorName, /* optional negator operator name */ + restrictionName, /* optional restrict. sel. procedure */ + joinName, /* optional join sel. procedure name */ + canHash, /* operator hashes */ + sortName1, /* optional first sort operator */ + sortName2); /* optional second sort operator */ } @@ -347,170 +410,170 @@ DefineAggregate(char *aggName, List *parameters) List *pl; foreach (pl, parameters) { - DefElem *defel = (DefElem *)lfirst(pl); + DefElem *defel = (DefElem *)lfirst(pl); - /* - * sfunc1 - */ - if (!strcasecmp(defel->defname, "sfunc1")) { - stepfunc1Name = defGetString(defel); - } else if (!strcasecmp(defel->defname, "basetype")) { - baseType = defGetString(defel); - } else if (!strcasecmp(defel->defname, "stype1")) { - stepfunc1Type = defGetString(defel); + /* + * sfunc1 + */ + if (!strcasecmp(defel->defname, "sfunc1")) { + stepfunc1Name = defGetString(defel); + } else if (!strcasecmp(defel->defname, "basetype")) { + baseType = defGetString(defel); + } else if (!strcasecmp(defel->defname, "stype1")) { + stepfunc1Type = defGetString(defel); - /* - * sfunc2 - */ - } else if (!strcasecmp(defel->defname, "sfunc2")) { - stepfunc2Name = defGetString(defel); - } else if (!strcasecmp(defel->defname, "stype2")) { - stepfunc2Type = defGetString(defel); - /* - * final - */ - } else if (!strcasecmp(defel->defname, "finalfunc")) { - finalfuncName = defGetString(defel); - /* - * initial conditions - */ - } else if (!strcasecmp(defel->defname, "initcond1")) { - init1 = defGetString(defel); - } else if (!strcasecmp(defel->defname, "initcond2")) { - init2 = defGetString(defel); - } else { - elog(NOTICE, "DefineAggregate: attribute \"%s\" not recognized", - defel->defname); - } + /* + * sfunc2 + */ + } else if (!strcasecmp(defel->defname, "sfunc2")) { + stepfunc2Name = defGetString(defel); + } else if (!strcasecmp(defel->defname, "stype2")) { + stepfunc2Type = defGetString(defel); + /* + * final + */ + } else if (!strcasecmp(defel->defname, "finalfunc")) { + finalfuncName = defGetString(defel); + /* + * initial conditions + */ + } else if (!strcasecmp(defel->defname, "initcond1")) { + init1 = defGetString(defel); + } else if (!strcasecmp(defel->defname, "initcond2")) { + init2 = defGetString(defel); + } else { + elog(NOTICE, "DefineAggregate: attribute \"%s\" not recognized", + defel->defname); + } } /* * make sure we have our required definitions */ if (baseType==NULL) - elog(WARN, "Define: \"basetype\" unspecified"); + elog(WARN, "Define: \"basetype\" unspecified"); if (stepfunc1Name!=NULL) { - if (stepfunc1Type==NULL) - elog(WARN, "Define: \"stype1\" unspecified"); + if (stepfunc1Type==NULL) + elog(WARN, "Define: \"stype1\" unspecified"); } if (stepfunc2Name!=NULL) { - if (stepfunc2Type==NULL) - elog(WARN, "Define: \"stype2\" unspecified"); + if (stepfunc2Type==NULL) + elog(WARN, "Define: \"stype2\" unspecified"); } /* * Most of the argument-checking is done inside of AggregateCreate */ - AggregateCreate(aggName, /* aggregate name */ - stepfunc1Name, /* first step function name */ - stepfunc2Name, /* second step function name */ - finalfuncName, /* final function name */ - baseType, /* type of object being aggregated */ - stepfunc1Type, /* return type of first function */ - stepfunc2Type, /* return type of second function */ - init1, /* first initial condition */ - init2); /* second initial condition */ + AggregateCreate(aggName, /* aggregate name */ + stepfunc1Name, /* first step function name */ + stepfunc2Name, /* second step function name */ + finalfuncName, /* final function name */ + baseType, /* type of object being aggregated */ + stepfunc1Type, /* return type of first function */ + stepfunc2Type, /* return type of second function */ + init1, /* first initial condition */ + init2); /* second initial condition */ /* XXX free palloc'd memory */ } /* * DefineType -- - * Registers a new type. + * Registers a new type. * */ void DefineType(char *typeName, List *parameters) { - int16 internalLength= 0; /* int2 */ - int16 externalLength= 0; /* int2 */ + int16 internalLength= 0; /* int2 */ + int16 externalLength= 0; /* int2 */ char *elemName = NULL; char *inputName = NULL; char *outputName = NULL; char *sendName = NULL; char *receiveName = NULL; - char *defaultValue = NULL; /* Datum */ - bool byValue = false; - char delimiter = DEFAULT_TYPDELIM; + char *defaultValue = NULL; /* Datum */ + bool byValue = false; + char delimiter = DEFAULT_TYPDELIM; char *shadow_type; - List *pl; - char alignment = 'i'; /* default alignment */ + List *pl; + char alignment = 'i'; /* default alignment */ /* * Type names can only be 15 characters long, so that the shadow type * can be created using the 16th character as necessary. */ if (strlen(typeName) >= (NAMEDATALEN - 1)) { - elog(WARN, "DefineType: type names must be %d characters or less", - NAMEDATALEN - 1); + elog(WARN, "DefineType: type names must be %d characters or less", + NAMEDATALEN - 1); } foreach(pl, parameters) { - DefElem *defel = (DefElem*)lfirst(pl); + DefElem *defel = (DefElem*)lfirst(pl); - if (!strcasecmp(defel->defname, "internallength")) { - internalLength = defGetTypeLength(defel); - }else if (!strcasecmp(defel->defname, "externallength")) { - externalLength = defGetTypeLength(defel); - }else if (!strcasecmp(defel->defname, "input")) { - inputName = defGetString(defel); - }else if (!strcasecmp(defel->defname, "output")) { - outputName = defGetString(defel); - }else if (!strcasecmp(defel->defname, "send")) { - sendName = defGetString(defel); - }else if (!strcasecmp(defel->defname, "delimiter")) { - char *p = defGetString(defel); - delimiter = p[0]; - }else if (!strcasecmp(defel->defname, "receive")) { - receiveName = defGetString(defel); - }else if (!strcasecmp(defel->defname, "element")) { - elemName = defGetString(defel); - }else if (!strcasecmp(defel->defname, "default")) { - defaultValue = defGetString(defel); - }else if (!strcasecmp(defel->defname, "passedbyvalue")) { - byValue = true; - }else if (!strcasecmp(defel->defname, "alignment")) { - char *a = defGetString(defel); - if (!strcasecmp(a, "double")) { - alignment = 'd'; - } else if (!strcasecmp(a, "int")) { - alignment = 'i'; - } else { - elog(WARN, "DefineType: \"%s\" alignment not recognized", - a); - } - }else { - elog(NOTICE, "DefineType: attribute \"%s\" not recognized", - defel->defname); - } + if (!strcasecmp(defel->defname, "internallength")) { + internalLength = defGetTypeLength(defel); + }else if (!strcasecmp(defel->defname, "externallength")) { + externalLength = defGetTypeLength(defel); + }else if (!strcasecmp(defel->defname, "input")) { + inputName = defGetString(defel); + }else if (!strcasecmp(defel->defname, "output")) { + outputName = defGetString(defel); + }else if (!strcasecmp(defel->defname, "send")) { + sendName = defGetString(defel); + }else if (!strcasecmp(defel->defname, "delimiter")) { + char *p = defGetString(defel); + delimiter = p[0]; + }else if (!strcasecmp(defel->defname, "receive")) { + receiveName = defGetString(defel); + }else if (!strcasecmp(defel->defname, "element")) { + elemName = defGetString(defel); + }else if (!strcasecmp(defel->defname, "default")) { + defaultValue = defGetString(defel); + }else if (!strcasecmp(defel->defname, "passedbyvalue")) { + byValue = true; + }else if (!strcasecmp(defel->defname, "alignment")) { + char *a = defGetString(defel); + if (!strcasecmp(a, "double")) { + alignment = 'd'; + } else if (!strcasecmp(a, "int")) { + alignment = 'i'; + } else { + elog(WARN, "DefineType: \"%s\" alignment not recognized", + a); + } + }else { + elog(NOTICE, "DefineType: attribute \"%s\" not recognized", + defel->defname); + } } /* * make sure we have our required definitions */ if (inputName==NULL) - elog(WARN, "Define: \"input\" unspecified"); + elog(WARN, "Define: \"input\" unspecified"); if (outputName==NULL) - elog(WARN, "Define: \"output\" unspecified"); + elog(WARN, "Define: \"output\" unspecified"); /* ---------------- - * now have TypeCreate do all the real work. + * now have TypeCreate do all the real work. * ---------------- */ - (void) TypeCreate(typeName, /* type name */ - InvalidOid, /* relation oid (n/a here) */ - internalLength, /* internal size */ - externalLength, /* external size */ - 'b', /* type-type (base type) */ - delimiter, /* array element delimiter */ - inputName, /* input procedure */ - outputName, /* output procedure */ - sendName, /* send procedure */ - receiveName, /* receive procedure */ - elemName, /* element type name */ - defaultValue, /* default type value */ - byValue, /* passed by value */ - alignment); + (void) TypeCreate(typeName, /* type name */ + InvalidOid, /* relation oid (n/a here) */ + internalLength, /* internal size */ + externalLength, /* external size */ + 'b', /* type-type (base type) */ + delimiter, /* array element delimiter */ + inputName, /* input procedure */ + outputName, /* output procedure */ + sendName, /* send procedure */ + receiveName, /* receive procedure */ + elemName, /* element type name */ + defaultValue, /* default type value */ + byValue, /* passed by value */ + alignment); /* ---------------- * When we create a true type (as opposed to a complex type) @@ -519,20 +582,20 @@ DefineType(char *typeName, List *parameters) */ shadow_type = makeArrayTypeName(typeName); - (void) TypeCreate(shadow_type, /* type name */ - InvalidOid, /* relation oid (n/a here) */ - -1, /* internal size */ - -1, /* external size */ - 'b', /* type-type (base type) */ - DEFAULT_TYPDELIM, /* array element delimiter */ - "array_in", /* input procedure */ - "array_out", /* output procedure */ - "array_out", /* send procedure */ - "array_in", /* receive procedure */ - typeName, /* element type name */ - defaultValue, /* default type value */ - false, /* never passed by value */ - alignment); + (void) TypeCreate(shadow_type, /* type name */ + InvalidOid, /* relation oid (n/a here) */ + -1, /* internal size */ + -1, /* external size */ + 'b', /* type-type (base type) */ + DEFAULT_TYPDELIM, /* array element delimiter */ + "array_in", /* input procedure */ + "array_out", /* output procedure */ + "array_out", /* send procedure */ + "array_in", /* receive procedure */ + typeName, /* element type name */ + defaultValue, /* default type value */ + false, /* never passed by value */ + alignment); pfree(shadow_type); } @@ -541,7 +604,7 @@ static char * defGetString(DefElem *def) { if (nodeTag(def->arg)!=T_String) - elog(WARN, "Define: \"%s\" = what?", def->defname); + elog(WARN, "Define: \"%s\" = what?", def->defname); return (strVal(def->arg)); } @@ -549,10 +612,10 @@ static int defGetTypeLength(DefElem *def) { if (nodeTag(def->arg)==T_Integer) - return (intVal(def->arg)); + return (intVal(def->arg)); else if (nodeTag(def->arg)==T_String && - !strcasecmp(strVal(def->arg),"variable")) - return -1; /* variable length */ + !strcasecmp(strVal(def->arg),"variable")) + return -1; /* variable length */ elog(WARN, "Define: \"%s\" = what?", def->defname); return -1; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index a7df82c0ff4..93ca5229181 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.2 1996/08/24 20:49:03 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.3 1996/10/31 09:08:10 bryanh Exp $ * *------------------------------------------------------------------------- */ @@ -367,7 +367,7 @@ ProcessUtility(Node *parsetree, } break; - case T_ViewStmt: /* VIEW */ + case T_ViewStmt: /* CREATE VIEW */ { ViewStmt *stmt = (ViewStmt *)parsetree; @@ -377,13 +377,13 @@ ProcessUtility(Node *parsetree, } break; - case T_ProcedureStmt: /* FUNCTION */ + case T_ProcedureStmt: /* CREATE FUNCTION */ commandTag = "CREATE"; CHECK_IF_ABORTED(); - DefineFunction((ProcedureStmt *)parsetree, dest); /* everything */ + CreateFunction((ProcedureStmt *)parsetree, dest); /* everything */ break; - case T_IndexStmt: + case T_IndexStmt: /* CREATE INDEX */ { IndexStmt *stmt = (IndexStmt *)parsetree; @@ -400,7 +400,7 @@ ProcessUtility(Node *parsetree, } break; - case T_RuleStmt: + case T_RuleStmt: /* CREATE RULE */ { RuleStmt *stmt = (RuleStmt *)parsetree; #ifndef NO_SECURITY