示例#1
0
/*
 * makeBoolConst -
 *	  creates a Const node representing a boolean value (can be NULL too)
 */
Node *
makeBoolConst(bool value, bool isnull)
{
	/* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
	return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
							  BoolGetDatum(value), isnull, true);
}
示例#2
0
	/*
	 * Transform the subscript expressions.
	 */
	foreach(idx, indirection)
	{
		A_Indices  *ai = (A_Indices *) lfirst(idx);
		Node	   *subexpr;

		Assert(IsA(ai, A_Indices));
		if (isSlice)
		{
			if (ai->lidx)
			{
				subexpr = transformExpr(pstate, ai->lidx);
				/* If it's not int4 already, try to coerce */
				subexpr = coerce_to_target_type(pstate,
												subexpr, exprType(subexpr),
												INT4OID, -1,
												COERCION_ASSIGNMENT,
												COERCE_IMPLICIT_CAST,
												-1);
				if (subexpr == NULL)
					ereport(ERROR,
							(errcode(ERRCODE_DATATYPE_MISMATCH),
							 errmsg("array subscript must have type integer"),
						parser_errposition(pstate, exprLocation(ai->lidx))));
			}
			else
			{
				/* Make a constant 1 */
				subexpr = (Node *) makeConst(INT4OID,
											 -1,
											 InvalidOid,
											 sizeof(int32),
											 Int32GetDatum(1),
											 false,
											 true);		/* pass by value */
			}
			lowerIndexpr = lappend(lowerIndexpr, subexpr);
		}
		subexpr = transformExpr(pstate, ai->uidx);
		/* If it's not int4 already, try to coerce */
		subexpr = coerce_to_target_type(pstate,
										subexpr, exprType(subexpr),
										INT4OID, -1,
										COERCION_ASSIGNMENT,
										COERCE_IMPLICIT_CAST,
										-1);
		if (subexpr == NULL)
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("array subscript must have type integer"),
					 parser_errposition(pstate, exprLocation(ai->uidx))));
		upperIndexpr = lappend(upperIndexpr, subexpr);
	}
示例#3
0
/*
 * makeNullConst -
 *	  creates a Const node representing a NULL of the specified type
 */
Const *
makeNullConst(Oid consttype)
{
	int16		typLen;
	bool		typByVal;

	get_typlenbyval(consttype, &typLen, &typByVal);
	return makeConst(consttype,
					 (int) typLen,
					 (Datum) 0,
					 true,
					 typByVal);
}
示例#4
0
/*
 * makeNullConst -
 *	  creates a Const node representing a NULL of the specified type/typmod
 *
 * This is a convenience routine that just saves a lookup of the type's
 * storage properties.
 */
Const *
makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
{
	int16		typLen;
	bool		typByVal;

	get_typlenbyval(consttype, &typLen, &typByVal);
	return makeConst(consttype,
					 consttypmod,
					 constcollid,
					 (int) typLen,
					 (Datum) 0,
					 true,
					 typByVal);
}
示例#5
0
/*
 * infer_tupledesc
 *
 * Given a stream, infer a TupleDesc based on the supertype of all
 * the casted types for each of the stream's columns
 */
static void
infer_tupledesc(StreamTargetsEntry *stream)
{
	HASH_SEQ_STATUS status;
	StreamColumnsEntry *entry;
	List *names = NIL;
	List *types = NIL;
	List *mods = NIL;
	List *collations = NIL;
	Const *preferred = makeConst(NUMERIC_OID, -1, 0, -1, 0, false, false);

	hash_seq_init(&status, stream->colstotypes);
	while ((entry = (StreamColumnsEntry *) hash_seq_search(&status)) != NULL)
	{
		char err[128];
		Oid supertype;
		char category;
		bool typispreferred;
		Oid t = exprType(linitial(entry->types));

		/*
		 * If there are any numeric types in our target types, we prepend a float8
		 * to the list of types to select from, as that is our preferred type when
		 * there is any ambiguity about how to interpret numeric types.
		 */
		get_type_category_preferred(t, &category, &typispreferred);
		if (category == TYPCATEGORY_NUMERIC)
			entry->types = lcons(preferred, entry->types);

		sprintf(err, "type conflict with stream \"%s\":", get_rel_name(stream->relid));
		supertype = select_common_type(NULL, entry->types, err, NULL);

		names = lappend(names, makeString(entry->name));
		types = lappend_int(types, supertype);
		mods = lappend_int(mods, -1);
		collations = lappend_int(collations, 0);
	}

	stream->desc = BuildDescFromLists(names, types, mods, collations);
}
示例#6
0
	/*
	 * Transform the subscript expressions.
	 */
	foreach(idx, indirection) {
		A_Indices *ai = (A_Indices *) lfirst(idx);
		node_n *subexpr;

		ASSERT(IS_A(ai, A_Indices));
		if (isSlice) {
			if (ai->lidx) {
				subexpr = xfrm_expr(pstate, ai->lidx);
				/* If it's not int4 already, try to coerce */
				subexpr = coerce_to_target_type(pstate, subexpr, expr_type(subexpr), INT4OID, -1,
					COERCION_ASSIGNMENT, COERCE_IMPLICIT_CAST, -1);
				if (subexpr == NULL)
					ereport(ERROR, (
					errcode(E_DATATYPE_MISMATCH),
					errmsg("array subscript must have type integer"),
				 	parser_errpos(pstate, expr_location(ai->lidx))));
			} else {
				/* Make a constant 1 */
				subexpr = (node_n *) makeConst(INT4OID, -1, INVALID_OID, sizeof(int32), INT32_TO_D(1),
					false, true);
					/* pass by value */
			}

			lowerIndexpr = lappend(lowerIndexpr, subexpr);
		}

		subexpr = xfrm_expr(pstate, ai->uidx);

		/* If it's not int4 already, try to coerce */
		subexpr = coerce_to_target_type(pstate, subexpr, expr_type(subexpr), INT4OID, -1, 
			COERCION_ASSIGNMENT, COERCE_IMPLICIT_CAST, -1);
		if (subexpr == NULL)
			ereport(ERROR, (
			errcode(E_DATATYPE_MISMATCH),
			errmsg("array subscript must have type integer"),
			parser_errpos(pstate, expr_location(ai->uidx))));

		upperIndexpr = lappend(upperIndexpr, subexpr);
	}
示例#7
0
	/*
	 * Transform the subscript expressions.
	 */
	foreach(idx, indirection)
	{
		A_Indices  *ai = castNode(A_Indices, lfirst(idx));
		Node	   *subexpr;

		if (isSlice)
		{
			if (ai->lidx)
			{
				subexpr = transformExpr(pstate, ai->lidx, pstate->p_expr_kind);
				/* If it's not int4 already, try to coerce */
				subexpr = coerce_to_target_type(pstate,
												subexpr, exprType(subexpr),
												INT4OID, -1,
												COERCION_ASSIGNMENT,
												COERCE_IMPLICIT_CAST,
												-1);
				if (subexpr == NULL)
					ereport(ERROR,
							(errcode(ERRCODE_DATATYPE_MISMATCH),
							 errmsg("array subscript must have type integer"),
						parser_errposition(pstate, exprLocation(ai->lidx))));
			}
			else if (!ai->is_slice)
			{
				/* Make a constant 1 */
				subexpr = (Node *) makeConst(INT4OID,
											 -1,
											 InvalidOid,
											 sizeof(int32),
											 Int32GetDatum(1),
											 false,
											 true);		/* pass by value */
			}
			else
			{
				/* Slice with omitted lower bound, put NULL into the list */
				subexpr = NULL;
			}
			lowerIndexpr = lappend(lowerIndexpr, subexpr);
		}
		else
			Assert(ai->lidx == NULL && !ai->is_slice);

		if (ai->uidx)
		{
			subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind);
			/* If it's not int4 already, try to coerce */
			subexpr = coerce_to_target_type(pstate,
											subexpr, exprType(subexpr),
											INT4OID, -1,
											COERCION_ASSIGNMENT,
											COERCE_IMPLICIT_CAST,
											-1);
			if (subexpr == NULL)
				ereport(ERROR,
						(errcode(ERRCODE_DATATYPE_MISMATCH),
						 errmsg("array subscript must have type integer"),
						 parser_errposition(pstate, exprLocation(ai->uidx))));
		}
		else
		{
			/* Slice with omitted upper bound, put NULL into the list */
			Assert(isSlice && ai->is_slice);
			subexpr = NULL;
		}
		upperIndexpr = lappend(upperIndexpr, subexpr);
	}
示例#8
0
文件: vasm-unit.cpp 项目: bjori/hhvm
Vreg Vunit::makeConst(double d) {
  union { double d; uint64_t i; } u;
  u.d = d;
  return makeConst(u.i);
}
示例#9
0
Node * my_mutator (Node *node, context_modifier *context)
  {
    if (node == NULL)
 			return NULL;
    /* elog(LOG,"%d",nodeTag(node)); */
    if(IsA(node,BoolExpr)){
      BoolExpr * bExpr =(BoolExpr *) node;
      if(bExpr->boolop == NOT_EXPR){
        /* elog(LOG,"\nTHERENOT\n"); */
        context->positive = !context->positive;
        Node * retour =  expression_tree_mutator(node, my_mutator, (void *) context);
        context->positive = !context->positive;
        return retour;
      }
      if(bExpr->boolop == OR_EXPR || bExpr->boolop == AND_EXPR){
        /*Pré traitement*/
        List * l_save = context->list_of_not_null_in_current;
        context->list_of_not_null_in_current = list_copy(l_save);
        if(context->positive){
          context->list_of_not_null_in_current = list_concat(context->list_of_not_null_in_current,list_nth(context->list_list_true,context->list_list_true->length - context->where_i_am - 1));
        }
        else{
          context->list_of_not_null_in_current = list_concat(context->list_of_not_null_in_current,list_nth(context->list_list_false,context->list_list_true->length - context->where_i_am - 1));
        }
        /* elog(LOG,"\n LIST_NOT_NULL: %s \n",nodeToString(context->list_of_not_null_in_current)); */
        context->where_i_am ++;
        Node * retour =  expression_tree_mutator(node, my_mutator, (void *) context);
        /*Post traitement*/
        context->list_of_not_null_in_current = l_save;

        return retour;
      }
    }
    if(IsA(node,Query)){
      Query * q = (Query *) node;
      /* context->current_varlevelsup ++; */
      List * save_current_trueVar = context->current_trueVar;
      context->current_trueVar = list_nth(context->trueVars,context->where_i_am_querry);
      context->where_i_am_querry = context->where_i_am_querry + 1;
      q->jointree = expression_tree_mutator((Node *) q->jointree, my_mutator, (void *) context);
      /* context->where_i_am_querry = context->where_i_am_querry - 1; */
      context->current_trueVar = save_current_trueVar;
      /* context->current_varlevelsup --; */
      return node;
    }
    if(IsA(node,OpExpr)){
      /* elog(LOG,"\nTHEREOP = \n"); */
      OpExpr * oExpr = (OpExpr *) node;
      if(context->positive && oExpr->opno == 518){ /*<>*/
        context->ready = true;
      }
      if(!context->positive && oExpr->opno == 96){ /* = */
        context->ready = true;
      }
      /* if(context->positive && oExpr->opno == 521){ #<{(| > |)}># */
      /*   context->ready = true; */
      /* } */
      if(oExpr->opno == 525){ /* >= */
        OpExpr * equa = makeNode(OpExpr);
        equa->opno = 96; /*=*/
        equa->args = list_concat(equa->args,oExpr->args);
        OpExpr * stric = makeNode(OpExpr);
        stric->opno = 521; /*>*/
        stric->args = list_concat(stric->args,oExpr->args);
        List * tmp = NULL;
        tmp = lappend(tmp,equa);
        tmp = lappend(tmp,stric);
        Node * result = expression_tree_mutator((Node *)makeBoolExpr(OR_EXPR,tmp,-1),my_mutator,context);
        return result;

      }
      if(oExpr->opno == 523){ /* <= */
        OpExpr * equa = makeNode(OpExpr);
        equa->opno = 96; /*=*/
        equa->args = list_concat(equa->args,oExpr->args);
        OpExpr * stric = makeNode(OpExpr);
        stric->opno = 97; /*<*/
        stric->args = list_concat(stric->args,oExpr->args);
        List * tmp = NULL;
        tmp = lappend(tmp,equa);
        tmp = lappend(tmp,stric);
        Node * result = expression_tree_mutator((Node *)makeBoolExpr(OR_EXPR,tmp,-1),my_mutator,context);
        return result;
      }
      /* if(context->positive && oExpr->opno == 97){ #<{(| < |)}># */
      /*   context->ready = true; */
      /* } */
      if(!context->positive && oExpr->opno == 1209){ /* LIKE */
        context->ready = true;
      }


      Node * result = expression_tree_mutator(node, my_mutator, (void *) context);
      if(context->constraint_to_add != NULL){
        if(!context->positive /* && oExpr->opno == 518 */){
          context->constraint_to_add = lappend(context->constraint_to_add,result);
          Node * to_return = makeBoolExpr(OR_EXPR,context->constraint_to_add,-1);
          context->constraint_to_add = NULL;
          context->ready = false;
          /* elog(LOG,"inter :%s\n",nodeToString(to_return)); */
          return to_return;
        }
        if(context->positive /* && oExpr->opno == 96 */){
          context->constraint_to_add = lappend(context->constraint_to_add,result);
          Node * to_return = makeBoolExpr(AND_EXPR,context->constraint_to_add,-1);
          context->constraint_to_add = NULL;
          context->ready = false;
          return to_return;
        }
      }
      else
        return result;

    }
 		if(context->ready && IsA(node, Var))
 		{
      /* elog(LOG,"\n LIST_NOT_NULL: %s \n",nodeToString(context->list_of_not_null_in_current)); */
      Var * v = (Var *) node;
      Var * rv = getTrueVar(context->current_trueVar,v);
      /* elog(LOG,"\nTRUE VARS : %s \n",nodeToString(context->current_trueVar)); */
      /* elog(LOG,"\nV check %s \n",nodeToString(v)); */
      /* elog(LOG,"\nRV check %s \n",nodeToString(rv)); */
      /* elog(LOG,"\nNOT NULL CUR: %s \n",nodeToString(context->list_of_not_null_in_current)); */
      if(!context->positive && !isInListTrueVar(context->list_of_not_null_in_current,rv)){
        /* elog(LOG,"\nHERE !\n"); */
        OpExpr * inf0 = makeNode(OpExpr);
        inf0->opno = 97; /*<*/
        inf0->args = lappend(inf0->args,node);
        Const * c0 = makeConst(23,-1,0,4,Int16GetDatum(0),false, true);
        inf0->args = lappend(inf0->args,c0);
        context->constraint_to_add = lappend(context->constraint_to_add,inf0);
      }
      if(context->positive){
        /* elog(LOG,"\nHERE !\n"); */
        OpExpr * inf0 = makeNode(OpExpr);
        inf0->opno = 521; /*>*/
        inf0->args = lappend(inf0->args,node);
        Const * c0 = makeConst(23,-1,0,4,Int16GetDatum(0),false, true);
        inf0->args = lappend(inf0->args,c0);
        context->constraint_to_add = lappend(context->constraint_to_add,inf0);
      }

 		}
 		return expression_tree_mutator(node, my_mutator, (void *) context);
  }
示例#10
0
/*
 * get_typdefault
 *	  Given a type OID, return the type's default value, if any.
 *
 *	  The result is a palloc'd expression node tree, or NULL if there
 *	  is no defined default for the datatype.
 *
 * NB: caller should be prepared to coerce result to correct datatype;
 * the returned expression tree might produce something of the wrong type.
 */
Node *
get_typdefault(Oid typid)
{
	HeapTuple	typeTuple;
	Form_pg_type type;
	Datum		datum;
	bool		isNull;
	Node	   *expr;

	typeTuple = SearchSysCache(TYPEOID,
							   ObjectIdGetDatum(typid),
							   0, 0, 0);
	if (!HeapTupleIsValid(typeTuple))
		elog(ERROR, "cache lookup failed for type %u", typid);
	type = (Form_pg_type) GETSTRUCT(typeTuple);

	/*
	 * typdefault and typdefaultbin are potentially null, so don't try to
	 * access 'em as struct fields. Must do it the hard way with
	 * SysCacheGetAttr.
	 */
	datum = SysCacheGetAttr(TYPEOID,
							typeTuple,
							Anum_pg_type_typdefaultbin,
							&isNull);

	if (!isNull)
	{
		/* We have an expression default */
		expr = stringToNode(DatumGetCString(DirectFunctionCall1(textout,
																datum)));
	}
	else
	{
		/* Perhaps we have a plain literal default */
		datum = SysCacheGetAttr(TYPEOID,
								typeTuple,
								Anum_pg_type_typdefault,
								&isNull);

		if (!isNull)
		{
			char	   *strDefaultVal;

			/* Convert text datum to C string */
			strDefaultVal = DatumGetCString(DirectFunctionCall1(textout,
																datum));
			/* Convert C string to a value of the given type */
			datum = OidInputFunctionCall(type->typinput, strDefaultVal,
										 getTypeIOParam(typeTuple), -1);
			/* Build a Const node containing the value */
			expr = (Node *) makeConst(typid,
									  type->typlen,
									  datum,
									  false,
									  type->typbyval);
			pfree(strDefaultVal);
		}
		else
		{
			/* No default */
			expr = NULL;
		}
	}

	ReleaseSysCache(typeTuple);

	return expr;
}
示例#11
0
/*
 * Copied from Postgres' src/backend/optimizer/util/clauses.c
 *
 * evaluate_expr: pre-evaluate a constant expression
 *
 * We use the executor's routine ExecEvalExpr() to avoid duplication of
 * code and ensure we get the same result as the executor would get.
 */
Expr *
evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod,
              Oid result_collation)
{
    EState	   *estate;
    ExprState  *exprstate;
    MemoryContext oldcontext;
    Datum		const_val;
    bool		const_is_null;
    int16		resultTypLen;
    bool		resultTypByVal;

    /*
     * To use the executor, we need an EState.
     */
    estate = CreateExecutorState();

    /* We can use the estate's working context to avoid memory leaks. */
    oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);

    /* Make sure any opfuncids are filled in. */
    fix_opfuncids((Node *) expr);

    /*
     * Prepare expr for execution.  (Note: we can't use ExecPrepareExpr
     * because it'd result in recursively invoking eval_const_expressions.)
     */
    exprstate = ExecInitExpr(expr, NULL);

    /*
     * And evaluate it.
     *
     * It is OK to use a default econtext because none of the ExecEvalExpr()
     * code used in this situation will use econtext.  That might seem
     * fortuitous, but it's not so unreasonable --- a constant expression does
     * not depend on context, by definition, n'est ce pas?
     */
    const_val = ExecEvalExprSwitchContext(exprstate,
                                          GetPerTupleExprContext(estate),
                                          &const_is_null, NULL);

    /* Get info needed about result datatype */
    get_typlenbyval(result_type, &resultTypLen, &resultTypByVal);

    /* Get back to outer memory context */
    MemoryContextSwitchTo(oldcontext);

    /*
     * Must copy result out of sub-context used by expression eval.
     *
     * Also, if it's varlena, forcibly detoast it.  This protects us against
     * storing TOAST pointers into plans that might outlive the referenced
     * data.  (makeConst would handle detoasting anyway, but it's worth a few
     * extra lines here so that we can do the copy and detoast in one step.)
     */
    if (!const_is_null)
    {
        if (resultTypLen == -1)
            const_val = PointerGetDatum(PG_DETOAST_DATUM_COPY(const_val));
        else
            const_val = datumCopy(const_val, resultTypByVal, resultTypLen);
    }

    /* Release all the junk we just created */
    FreeExecutorState(estate);

    /*
     * Make the constant result node.
     */
    return (Expr *) makeConst(result_type, result_typmod, result_collation,
                              resultTypLen,
                              const_val, const_is_null,
                              resultTypByVal);
}