diff options
Diffstat (limited to 'src/backend/parser/parser.c')
-rw-r--r-- | src/backend/parser/parser.c | 844 |
1 files changed, 449 insertions, 395 deletions
diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c index ab4276055cd..99c6ce2bfdb 100644 --- a/src/backend/parser/parser.c +++ b/src/backend/parser/parser.c @@ -6,14 +6,14 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.22 1997/08/22 07:12:45 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.23 1997/09/07 04:44:50 momjian Exp $ * *------------------------------------------------------------------------- */ #include <string.h> #include <stdio.h> #include <pwd.h> -#include <sys/param.h> /* for MAXPATHLEN */ +#include <sys/param.h> /* for MAXPATHLEN */ #include "postgres.h" #include "parser/catalog_utils.h" @@ -34,456 +34,510 @@ #include "catalog/pg_aggregate.h" #include "catalog/pg_type.h" #include "access/heapam.h" -#include "optimizer/clauses.h" +#include "optimizer/clauses.h" -void init_io(); /* from scan.l */ -void parser_init(Oid *typev, int nargs); /* from gram.y */ -int yyparse(); /* from gram.c */ +void init_io(); /* from scan.l */ +void parser_init(Oid * typev, int nargs); /* from gram.y */ +int yyparse(); /* from gram.c */ -char *parseString; /* the char* which holds the string to be parsed */ -char *parseCh; /* a pointer used during parsing to walk down ParseString*/ +char *parseString; /* the char* which holds the string to be + * parsed */ +char *parseCh; /* a pointer used during parsing to walk + * down ParseString */ -List *parsetree = NIL; +List *parsetree = NIL; #ifdef SETS_FIXED -static void fixupsets(); -static void define_sets(); +static void fixupsets(); +static void define_sets(); + #endif /* * parser-- returns a list of parse trees - * - * CALLER is responsible for free'ing the list returned + * + * CALLER is responsible for free'ing the list returned */ -QueryTreeList * -parser(char *str, Oid *typev, int nargs) +QueryTreeList * +parser(char *str, Oid * typev, int nargs) { - QueryTreeList* queryList; - int yyresult; + QueryTreeList *queryList; + int yyresult; #if defined(FLEX_SCANNER) - extern void DeleteBuffer(void); -#endif /* FLEX_SCANNER */ - - init_io(); - - /* Set things up to read from the string, if there is one */ - parseString = (char *) palloc(strlen(str) + 1); - memmove(parseString,str,strlen(str)+1); - - parser_init(typev, nargs); - yyresult = yyparse(); + extern void DeleteBuffer(void); + +#endif /* FLEX_SCANNER */ + + init_io(); + + /* Set things up to read from the string, if there is one */ + parseString = (char *) palloc(strlen(str) + 1); + memmove(parseString, str, strlen(str) + 1); + + parser_init(typev, nargs); + yyresult = yyparse(); #if defined(FLEX_SCANNER) - DeleteBuffer(); -#endif /* FLEX_SCANNER */ - - clearerr(stdin); - - if (yyresult) { /* error */ - return((QueryTreeList*)NULL); - } - - queryList = parse_analyze(parsetree); - + DeleteBuffer(); +#endif /* FLEX_SCANNER */ + + clearerr(stdin); + + if (yyresult) + { /* error */ + return ((QueryTreeList *) NULL); + } + + queryList = parse_analyze(parsetree); + #ifdef SETS_FIXED - /* Fixing up sets calls the parser, so it reassigns the global - * variable parsetree. So save the real parsetree. - */ - savetree = parsetree; - foreach (parse, savetree) { /* savetree is really a list of parses */ - /* find set definitions embedded in query */ - fixupsets((Query *)lfirst(parse)); + /* + * Fixing up sets calls the parser, so it reassigns the global + * variable parsetree. So save the real parsetree. + */ + savetree = parsetree; + foreach(parse, savetree) + { /* savetree is really a list of parses */ + + /* find set definitions embedded in query */ + fixupsets((Query *) lfirst(parse)); - } - return savetree; -#endif + } + return savetree; +#endif - return queryList; + return queryList; } #ifdef SETS_FIXED static void -fixupsets(Query *parse) +fixupsets(Query * parse) { - if (parse == NULL) - return; - if (parse->commandType==CMD_UTILITY) /* utility */ - return; - if (parse->commandType!=CMD_INSERT) - return; - define_sets(parse); + if (parse == NULL) + return; + if (parse->commandType == CMD_UTILITY) /* utility */ + return; + if (parse->commandType != CMD_INSERT) + return; + define_sets(parse); } /* Recursively find all of the Consts in the parsetree. Some of * these may represent a set. The value of the Const will be the - * query (a string) which defines the set. Call SetDefine to define + * query (a string) which defines the set. Call SetDefine to define * the set, and store the OID of the new set in the Const instead. */ static void -define_sets(Node *clause) +define_sets(Node * clause) { - Oid setoid; - Type t = type("oid"); - Oid typeoid = typeid(t); - Size oidsize = tlen(t); - bool oidbyval = tbyval(t); - - if (clause==NULL) { - return; - } else if (IsA(clause,LispList)) { - define_sets(lfirst(clause)); - define_sets(lnext(clause)); - } else if (IsA(clause,Const)) { - if (get_constisnull((Const)clause) || - !get_constisset((Const)clause)) { - return; + Oid setoid; + Type t = type("oid"); + Oid typeoid = typeid(t); + Size oidsize = tlen(t); + bool oidbyval = tbyval(t); + + if (clause == NULL) + { + return; + } + else if (IsA(clause, LispList)) + { + define_sets(lfirst(clause)); + define_sets(lnext(clause)); + } + else if (IsA(clause, Const)) + { + if (get_constisnull((Const) clause) || + !get_constisset((Const) clause)) + { + return; + } + setoid = SetDefine(((Const *) clause)->constvalue, + get_id_typname(((Const *) clause)->consttype)); + set_constvalue((Const) clause, setoid); + set_consttype((Const) clause, typeoid); + set_constlen((Const) clause, oidsize); + set_constbyval((Const) clause, oidbyval); + } + else if (IsA(clause, Iter)) + { + define_sets(((Iter *) clause)->iterexpr); + } + else if (single_node(clause)) + { + return; + } + else if (or_clause(clause)) + { + List *temp; + + /* mapcan */ + foreach(temp, ((Expr *) clause)->args) + { + define_sets(lfirst(temp)); + } } - setoid = SetDefine(((Const*)clause)->constvalue, - get_id_typname(((Const*)clause)->consttype)); - set_constvalue((Const)clause, setoid); - set_consttype((Const)clause,typeoid); - set_constlen((Const)clause,oidsize); - set_constbyval((Const)clause,oidbyval); - } else if ( IsA(clause,Iter) ) { - define_sets(((Iter*)clause)->iterexpr); - } else if (single_node (clause)) { - return; - } else if (or_clause(clause)) { - List *temp; - /* mapcan */ - foreach (temp, ((Expr*)clause)->args) { - define_sets(lfirst(temp)); + else if (is_funcclause(clause)) + { + List *temp; + + /* mapcan */ + foreach(temp, ((Expr *) clause)->args) + { + define_sets(lfirst(temp)); + } } - } else if (is_funcclause (clause)) { - List *temp; - /* mapcan */ - foreach(temp, ((Expr*)clause)->args) { - define_sets(lfirst(temp)); + else if (IsA(clause, ArrayRef)) + { + define_sets(((ArrayRef *) clause)->refassgnexpr); + } + else if (not_clause(clause)) + { + define_sets(get_notclausearg(clause)); + } + else if (is_opclause(clause)) + { + define_sets(get_leftop(clause)); + define_sets(get_rightop(clause)); } - } else if (IsA(clause,ArrayRef)) { - define_sets(((ArrayRef*)clause)->refassgnexpr); - } else if (not_clause (clause)) { - define_sets (get_notclausearg (clause)); - } else if (is_opclause (clause)) { - define_sets(get_leftop (clause)); - define_sets(get_rightop (clause)); - } } + #endif /* not used -#define PSIZE(PTR) (*((int32 *)(PTR) - 1)) +#define PSIZE(PTR) (*((int32 *)(PTR) - 1)) */ -Node * -parser_typecast(Value *expr, TypeName *typename, int typlen) +Node * +parser_typecast(Value * expr, TypeName * typename, int typlen) { - /* check for passing non-ints */ - Const *adt; - Datum lcp; - Type tp; - char type_string[16]; - int32 len; - char *cp = NULL; - char *const_string = NULL; - bool string_palloced = false; - - switch(nodeTag(expr)) { - case T_String: - const_string = DatumGetPointer(expr->val.str); - break; - case T_Integer: - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string, "%d", expr->val.ival); - break; - default: - elog(WARN, - "parser_typecast: cannot cast this expression to type \"%s\"", - typename->name); - } - - if (typename->arrayBounds != NIL) { - sprintf(type_string,"_%s", typename->name); - tp = (Type) type(type_string); - } else { - tp = (Type) type(typename->name); - } - - len = tlen(tp); - -#if 0 /* fix me */ - switch ( CInteger(lfirst(expr)) ) { - case INT4OID: /* int4 */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string,"%d", ((Const*)lnext(expr))->constvalue); - break; - - case NAMEOID: /* char16 */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string,"%s", ((Const*)lnext(expr))->constvalue); - break; - - case CHAROID: /* char */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string,"%c", ((Const)lnext(expr))->constvalue); - break; - - case FLOAT8OID:/* float8 */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string,"%f", ((Const)lnext(expr))->constvalue); - break; - - case CASHOID: /* money */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string,"%d", - (int) ((Const*)expr)->constvalue); - break; - - case TEXTOID: /* text */ - const_string = DatumGetPointer(((Const)lnext(expr))->constvalue); - const_string = (char *) textout((struct varlena *)const_string); - break; - - case UNKNOWNOID: /* unknown */ - const_string = DatumGetPointer(((Const)lnext(expr))->constvalue); - const_string = (char *) textout((struct varlena *)const_string); - break; - - default: - elog(WARN,"unknown type %d", CInteger(lfirst(expr))); - } + /* check for passing non-ints */ + Const *adt; + Datum lcp; + Type tp; + char type_string[16]; + int32 len; + char *cp = NULL; + char *const_string = NULL; + bool string_palloced = false; + + switch (nodeTag(expr)) + { + case T_String: + const_string = DatumGetPointer(expr->val.str); + break; + case T_Integer: + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%d", expr->val.ival); + break; + default: + elog(WARN, + "parser_typecast: cannot cast this expression to type \"%s\"", + typename->name); + } + + if (typename->arrayBounds != NIL) + { + sprintf(type_string, "_%s", typename->name); + tp = (Type) type(type_string); + } + else + { + tp = (Type) type(typename->name); + } + + len = tlen(tp); + +#if 0 /* fix me */ + switch (CInteger(lfirst(expr))) + { + case INT4OID: /* int4 */ + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%d", ((Const *) lnext(expr))->constvalue); + break; + + case NAMEOID: /* char16 */ + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%s", ((Const *) lnext(expr))->constvalue); + break; + + case CHAROID: /* char */ + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%c", ((Const) lnext(expr))->constvalue); + break; + + case FLOAT8OID: /* float8 */ + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%f", ((Const) lnext(expr))->constvalue); + break; + + case CASHOID: /* money */ + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%d", + (int) ((Const *) expr)->constvalue); + break; + + case TEXTOID: /* text */ + const_string = DatumGetPointer(((Const) lnext(expr))->constvalue); + const_string = (char *) textout((struct varlena *) const_string); + break; + + case UNKNOWNOID: /* unknown */ + const_string = DatumGetPointer(((Const) lnext(expr))->constvalue); + const_string = (char *) textout((struct varlena *) const_string); + break; + + default: + elog(WARN, "unknown type %d", CInteger(lfirst(expr))); + } #endif - cp = instr2 (tp, const_string, typlen); - - if (!tbyvalue(tp)) { + cp = instr2(tp, const_string, typlen); + + if (!tbyvalue(tp)) + { /* - if (len >= 0 && len != PSIZE(cp)) { - char *pp; - pp = (char *) palloc(len); - memmove(pp, cp, len); - cp = pp; - } + if (len >= 0 && len != PSIZE(cp)) { + char *pp; + pp = (char *) palloc(len); + memmove(pp, cp, len); + cp = pp; + } */ - lcp = PointerGetDatum(cp); - } else { - switch(len) { - case 1: - lcp = Int8GetDatum(cp); - break; - case 2: - lcp = Int16GetDatum(cp); - break; - case 4: - lcp = Int32GetDatum(cp); - break; - default: - lcp = PointerGetDatum(cp); - break; + lcp = PointerGetDatum(cp); + } + else + { + switch (len) + { + case 1: + lcp = Int8GetDatum(cp); + break; + case 2: + lcp = Int16GetDatum(cp); + break; + case 4: + lcp = Int32GetDatum(cp); + break; + default: + lcp = PointerGetDatum(cp); + break; + } } - } - - adt = makeConst(typeid(tp), - len, - (Datum)lcp , - false, - tbyvalue(tp), - false, /* not a set */ - true /* is cast */); - - if (string_palloced) - pfree(const_string); - - return (Node*)adt; + + adt = makeConst(typeid(tp), + len, + (Datum) lcp, + false, + tbyvalue(tp), + false, /* not a set */ + true /* is cast */ ); + + if (string_palloced) + pfree(const_string); + + return (Node *) adt; } -Node * -parser_typecast2(Node *expr, Oid exprType, Type tp, int typlen) +Node * +parser_typecast2(Node * expr, Oid exprType, Type tp, int typlen) { - /* check for passing non-ints */ - Const *adt; - Datum lcp; - int32 len = tlen(tp); - char *cp = NULL; - - char *const_string = NULL; - bool string_palloced = false; - - Assert(IsA(expr,Const)); - - switch (exprType) { - case 0: /* NULL */ - break; - case INT4OID: /* int4 */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string,"%d", - (int) ((Const*)expr)->constvalue); - break; - case NAMEOID: /* char16 */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string,"%s", - (char*) ((Const*)expr)->constvalue); - break; - case CHAROID: /* char */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string,"%c", - (char) ((Const*)expr)->constvalue); - break; - case FLOAT4OID: /* float4 */ + /* check for passing non-ints */ + Const *adt; + Datum lcp; + int32 len = tlen(tp); + char *cp = NULL; + + char *const_string = NULL; + bool string_palloced = false; + + Assert(IsA(expr, Const)); + + switch (exprType) { - float32 floatVal = - DatumGetFloat32(((Const*)expr)->constvalue); - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string,"%f", *floatVal); - break; + case 0: /* NULL */ + break; + case INT4OID: /* int4 */ + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%d", + (int) ((Const *) expr)->constvalue); + break; + case NAMEOID: /* char16 */ + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%s", + (char *) ((Const *) expr)->constvalue); + break; + case CHAROID: /* char */ + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%c", + (char) ((Const *) expr)->constvalue); + break; + case FLOAT4OID: /* float4 */ + { + float32 floatVal = + DatumGetFloat32(((Const *) expr)->constvalue); + + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%f", *floatVal); + break; + } + case FLOAT8OID: /* float8 */ + { + float64 floatVal = + DatumGetFloat64(((Const *) expr)->constvalue); + + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%f", *floatVal); + break; + } + case CASHOID: /* money */ + const_string = (char *) palloc(256); + string_palloced = true; + sprintf(const_string, "%d", + (long) ((Const *) expr)->constvalue); + break; + case TEXTOID: /* text */ + const_string = + DatumGetPointer(((Const *) expr)->constvalue); + const_string = (char *) textout((struct varlena *) const_string); + break; + case UNKNOWNOID: /* unknown */ + const_string = + DatumGetPointer(((Const *) expr)->constvalue); + const_string = (char *) textout((struct varlena *) const_string); + break; + default: + elog(WARN, "unknown type %u ", exprType); } - case FLOAT8OID:/* float8 */ + + if (!exprType) { - float64 floatVal = - DatumGetFloat64(((Const*)expr)->constvalue); - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string,"%f", *floatVal); - break; + adt = makeConst(typeid(tp), + (Size) 0, + (Datum) NULL, + true, /* isnull */ + false, /* was omitted */ + false, /* not a set */ + true /* is cast */ ); + return ((Node *) adt); } - case CASHOID: /* money */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string,"%d", - (long) ((Const*)expr)->constvalue); - break; - case TEXTOID: /* text */ - const_string = - DatumGetPointer(((Const*)expr)->constvalue ); - const_string = (char *) textout((struct varlena *)const_string); - break; - case UNKNOWNOID: /* unknown */ - const_string = - DatumGetPointer(((Const*)expr)->constvalue ); - const_string = (char *) textout((struct varlena *)const_string); - break; - default: - elog(WARN,"unknown type %u ",exprType); - } - - if (!exprType) { - adt = makeConst(typeid(tp), - (Size) 0, - (Datum) NULL, - true, /* isnull */ - false, /* was omitted */ - false, /* not a set */ - true /* is cast */); - return ((Node*) adt); - } - - cp = instr2 (tp, const_string, typlen); - - - if (!tbyvalue(tp)) { + + cp = instr2(tp, const_string, typlen); + + + if (!tbyvalue(tp)) + { /* - if (len >= 0 && len != PSIZE(cp)) { - char *pp; - pp = (char *) palloc(len); - memmove(pp, cp, len); - cp = pp; - } + if (len >= 0 && len != PSIZE(cp)) { + char *pp; + pp = (char *) palloc(len); + memmove(pp, cp, len); + cp = pp; + } */ - lcp = PointerGetDatum(cp); - } else { - switch(len) { - case 1: - lcp = Int8GetDatum(cp); - break; - case 2: - lcp = Int16GetDatum(cp); - break; - case 4: - lcp = Int32GetDatum(cp); - break; - default: - lcp = PointerGetDatum(cp); - break; + lcp = PointerGetDatum(cp); + } + else + { + switch (len) + { + case 1: + lcp = Int8GetDatum(cp); + break; + case 2: + lcp = Int16GetDatum(cp); + break; + case 4: + lcp = Int32GetDatum(cp); + break; + default: + lcp = PointerGetDatum(cp); + break; + } } - } - - adt = makeConst(typeid(tp), - (Size)len, - (Datum)lcp, - false, - false, /*was omitted*/ - false, /* not a set */ - true /* is cast */); - /* - printf("adt %s : %u %d %d\n",CString(expr),typeid(tp) , - len,cp); - */ - if (string_palloced) pfree(const_string); - - return ((Node*) adt); + + adt = makeConst(typeid(tp), + (Size) len, + (Datum) lcp, + false, + false, /* was omitted */ + false, /* not a set */ + true /* is cast */ ); + + /* + * printf("adt %s : %u %d %d\n",CString(expr),typeid(tp) , len,cp); + */ + if (string_palloced) + pfree(const_string); + + return ((Node *) adt); } -Aggreg * -ParseAgg(char *aggname, Oid basetype, Node *target) +Aggreg * +ParseAgg(char *aggname, Oid basetype, Node * target) { - Oid fintype; - Oid vartype; - Oid xfn1; - Form_pg_aggregate aggform; - Aggreg *aggreg; - HeapTuple theAggTuple; - - theAggTuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggname), - ObjectIdGetDatum(basetype), - 0, 0); - if (!HeapTupleIsValid(theAggTuple)) { - elog(WARN, "aggregate %s does not exist", aggname); - } - - aggform = (Form_pg_aggregate) GETSTRUCT(theAggTuple); - fintype = aggform->aggfinaltype; - xfn1 = aggform->aggtransfn1; - - if (nodeTag(target) != T_Var && nodeTag(target) != T_Expr) - elog(WARN, "parser: aggregate can only be applied on an attribute or expression"); - - /* only aggregates with transfn1 need a base type */ - if (OidIsValid(xfn1)) { - basetype = aggform->aggbasetype; - if (nodeTag(target) == T_Var) - vartype = ((Var*)target)->vartype; - else - vartype = ((Expr*)target)->typeOid; - - if (basetype != vartype) { - Type tp1, tp2; - - tp1 = get_id_type(basetype); - tp2 = get_id_type(vartype); - elog(NOTICE, "Aggregate type mismatch:"); - elog(WARN, "%s works on %s, not %s", aggname, - tname(tp1), tname(tp2)); - } - } - - aggreg = makeNode(Aggreg); - aggreg->aggname = pstrdup(aggname); - aggreg->basetype = aggform->aggbasetype; - aggreg->aggtype = fintype; - - aggreg->target = target; - - return aggreg; -} + Oid fintype; + Oid vartype; + Oid xfn1; + Form_pg_aggregate aggform; + Aggreg *aggreg; + HeapTuple theAggTuple; + theAggTuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggname), + ObjectIdGetDatum(basetype), + 0, 0); + if (!HeapTupleIsValid(theAggTuple)) + { + elog(WARN, "aggregate %s does not exist", aggname); + } + + aggform = (Form_pg_aggregate) GETSTRUCT(theAggTuple); + fintype = aggform->aggfinaltype; + xfn1 = aggform->aggtransfn1; + + if (nodeTag(target) != T_Var && nodeTag(target) != T_Expr) + elog(WARN, "parser: aggregate can only be applied on an attribute or expression"); + + /* only aggregates with transfn1 need a base type */ + if (OidIsValid(xfn1)) + { + basetype = aggform->aggbasetype; + if (nodeTag(target) == T_Var) + vartype = ((Var *) target)->vartype; + else + vartype = ((Expr *) target)->typeOid; + + if (basetype != vartype) + { + Type tp1, + tp2; + + tp1 = get_id_type(basetype); + tp2 = get_id_type(vartype); + elog(NOTICE, "Aggregate type mismatch:"); + elog(WARN, "%s works on %s, not %s", aggname, + tname(tp1), tname(tp2)); + } + } + + aggreg = makeNode(Aggreg); + aggreg->aggname = pstrdup(aggname); + aggreg->basetype = aggform->aggbasetype; + aggreg->aggtype = fintype; + + aggreg->target = target; + + return aggreg; +} |