static void
createJoinCondition (Query *query, SublinkInfo *info, bool isTargetRewrite)
{
	JoinExpr *join;
	Node *condition;
	Node *Csub;
	Node *CsubPlus;

	if (info->sublink->subLinkType == ANY_SUBLINK || info->sublink->subLinkType == ALL_SUBLINK)
	{
		/* generate Csub and CsubPlus from sublink condition */
		if (info->targetVar)
		{
			Csub = copyObject(info->targetVar);
		}
		else
		{
			Csub = generateCsub (info);
		}

		CsubPlus = generateCsubPlus (info, list_length(query->rtable) - 1);

		/* create condition */
		if (info->sublink->subLinkType == ANY_SUBLINK)
		{
			/* C_sub' OR NOT C_sub */
			condition = (Node *) makeBoolExpr(NOT_EXPR, list_make1(Csub));
			condition = (Node *) makeBoolExpr(OR_EXPR, list_make2(CsubPlus, condition));
		}
		if (info->sublink->subLinkType == ALL_SUBLINK)
		{
			/* C_sub OR NOT C_sub' */
			condition = (Node *) makeBoolExpr(NOT_EXPR, list_make1(CsubPlus));
			condition = (Node *) makeBoolExpr(OR_EXPR, list_make2(Csub, condition));
		}
	}
	else
	{
		condition = makeBoolConst(true, false);
	}

	if (list_length(query->rtable) > 1)
	{
		join = (JoinExpr *) linitial(query->jointree->fromlist);
		join->quals = condition;
	}
	else
	{
		query->jointree->quals = condition;
	}
}
Exemple #2
0
void sh_foo(char* command){
	struct expr * testexpr;
	testexpr = makeIntExpr((int) millis());
	ttprintln(toString(testexpr));
	testexpr = makeFloatExpr(3.14159265358979);
	ttprintln(toString(testexpr));
	testexpr = makeStringExpr("Hello, world!");
	ttprintln(toString(testexpr));
	testexpr = makeBoolExpr(1);
	ttprintln(toString(testexpr));
	testexpr = makeBoolExpr(0);
	ttprintln(toString(testexpr));
	/*
	struct StringListNode* tokens = tokenize(fileBuffer->firstLine);
	ttprintln("printing tokens:");
	while(tokens){
		ttprintln(tokens->str);
		tokens = tokens->next;
	}*/
}
Exemple #3
0
/*
 * get_proposed_default_constraint
 *
 * This function returns the negation of new_part_constraints, which
 * would be an integral part of the default partition constraints after
 * addition of the partition to which the new_part_constraints belongs.
 */
List *
get_proposed_default_constraint(List *new_part_constraints)
{
	Expr	   *defPartConstraint;

	defPartConstraint = make_ands_explicit(new_part_constraints);

	/*
	 * Derive the partition constraints of default partition by negating the
	 * given partition constraints. The partition constraint never evaluates
	 * to NULL, so negating it like this is safe.
	 */
	defPartConstraint = makeBoolExpr(NOT_EXPR,
									 list_make1(defPartConstraint),
									 -1);

	/* Simplify, to put the negated expression into canonical form */
	defPartConstraint =
		(Expr *) eval_const_expressions(NULL,
										(Node *) defPartConstraint);
	defPartConstraint = canonicalize_qual(defPartConstraint, true);

	return make_ands_implicit(defPartConstraint);
}
Exemple #4
0
/*
 * Get any row security quals and check quals that should be applied to the
 * specified RTE.
 *
 * In addition, hasRowSecurity is set to true if row level security is enabled
 * (even if this RTE doesn't have any row security quals), and hasSubLinks is
 * set to true if any of the quals returned contain sublinks.
 */
void
get_row_security_policies(Query *root, CmdType commandType, RangeTblEntry *rte,
						  int rt_index, List **securityQuals,
						  List **withCheckOptions, bool *hasRowSecurity,
						  bool *hasSubLinks)
{
	Expr	   *rowsec_expr = NULL;
	Expr	   *rowsec_with_check_expr = NULL;
	Expr	   *hook_expr_restrictive = NULL;
	Expr	   *hook_with_check_expr_restrictive = NULL;
	Expr	   *hook_expr_permissive = NULL;
	Expr	   *hook_with_check_expr_permissive = NULL;

	List	   *rowsec_policies;
	List	   *hook_policies_restrictive = NIL;
	List	   *hook_policies_permissive = NIL;

	Relation	rel;
	Oid			user_id;
	int			rls_status;
	bool		defaultDeny = false;

	/* Defaults for the return values */
	*securityQuals = NIL;
	*withCheckOptions = NIL;
	*hasRowSecurity = false;
	*hasSubLinks = false;

	/* If this is not a normal relation, just return immediately */
	if (rte->relkind != RELKIND_RELATION)
		return;

	/* Switch to checkAsUser if it's set */
	user_id = rte->checkAsUser ? rte->checkAsUser : GetUserId();

	/* Determine the state of RLS for this, pass checkAsUser explicitly */
	rls_status = check_enable_rls(rte->relid, rte->checkAsUser, false);

	/* If there is no RLS on this table at all, nothing to do */
	if (rls_status == RLS_NONE)
		return;

	/*
	 * RLS_NONE_ENV means we are not doing any RLS now, but that may change
	 * with changes to the environment, so we mark it as hasRowSecurity to
	 * force a re-plan when the environment changes.
	 */
	if (rls_status == RLS_NONE_ENV)
	{
		/*
		 * Indicate that this query may involve RLS and must therefore be
		 * replanned if the environment changes (GUCs, role), but we are not
		 * adding anything here.
		 */
		*hasRowSecurity = true;

		return;
	}

	/* Grab the built-in policies which should be applied to this relation. */
	rel = heap_open(rte->relid, NoLock);

	rowsec_policies = pull_row_security_policies(commandType, rel,
												 user_id);

	/*
	 * Check if this is only the default-deny policy.
	 *
	 * Normally, if the table has row security enabled but there are no
	 * policies, we use a default-deny policy and not allow anything. However,
	 * when an extension uses the hook to add their own policies, we don't
	 * want to include the default deny policy or there won't be any way for a
	 * user to use an extension exclusively for the policies to be used.
	 */
	if (((RowSecurityPolicy *) linitial(rowsec_policies))->policy_id
		== InvalidOid)
		defaultDeny = true;

	/* Now that we have our policies, build the expressions from them. */
	process_policies(root, rowsec_policies, rt_index, &rowsec_expr,
					 &rowsec_with_check_expr, hasSubLinks, OR_EXPR);

	/*
	 * Also, allow extensions to add their own policies.
	 *
	 * extensions can add either permissive or restrictive policies.
	 *
	 * Note that, as with the internal policies, if multiple policies are
	 * returned then they will be combined into a single expression with all
	 * of them OR'd (for permissive) or AND'd (for restrictive) together.
	 *
	 * If only a USING policy is returned by the extension then it will be
	 * used for WITH CHECK as well, similar to how internal policies are
	 * handled.
	 *
	 * The only caveat to this is that if there are NO internal policies
	 * defined, there ARE policies returned by the extension, and RLS is
	 * enabled on the table, then we will ignore the internally-generated
	 * default-deny policy and use only the policies returned by the
	 * extension.
	 */
	if (row_security_policy_hook_restrictive)
	{
		hook_policies_restrictive = (*row_security_policy_hook_restrictive) (commandType, rel);

		/* Build the expression from any policies returned. */
		if (hook_policies_restrictive != NIL)
			process_policies(root, hook_policies_restrictive, rt_index,
							 &hook_expr_restrictive,
							 &hook_with_check_expr_restrictive,
							 hasSubLinks,
							 AND_EXPR);
	}

	if (row_security_policy_hook_permissive)
	{
		hook_policies_permissive = (*row_security_policy_hook_permissive) (commandType, rel);

		/* Build the expression from any policies returned. */
		if (hook_policies_permissive != NIL)
			process_policies(root, hook_policies_permissive, rt_index,
							 &hook_expr_permissive,
							 &hook_with_check_expr_permissive, hasSubLinks,
							 OR_EXPR);
	}

	/*
	 * If the only built-in policy is the default-deny one, and hook policies
	 * exist, then use the hook policies only and do not apply the
	 * default-deny policy.  Otherwise, we will apply both sets below.
	 */
	if (defaultDeny &&
		(hook_policies_restrictive != NIL || hook_policies_permissive != NIL))
	{
		rowsec_expr = NULL;
		rowsec_with_check_expr = NULL;
	}

	/*
	 * For INSERT or UPDATE, we need to add the WITH CHECK quals to Query's
	 * withCheckOptions to verify that any new records pass the WITH CHECK
	 * policy (this will be a copy of the USING policy, if no explicit WITH
	 * CHECK policy exists).
	 */
	if (commandType == CMD_INSERT || commandType == CMD_UPDATE)
	{
		/*
		 * WITH CHECK OPTIONS wants a WCO node which wraps each Expr, so
		 * create them as necessary.
		 */

		/*
		 * Handle any restrictive policies first.
		 *
		 * They can simply be added.
		 */
		if (hook_with_check_expr_restrictive)
		{
			WithCheckOption *wco;

			wco = (WithCheckOption *) makeNode(WithCheckOption);
			wco->kind = commandType == CMD_INSERT ? WCO_RLS_INSERT_CHECK :
				WCO_RLS_UPDATE_CHECK;
			wco->relname = pstrdup(RelationGetRelationName(rel));
			wco->qual = (Node *) hook_with_check_expr_restrictive;
			wco->cascaded = false;
			*withCheckOptions = lappend(*withCheckOptions, wco);
		}

		/*
		 * Handle built-in policies, if there are no permissive policies from
		 * the hook.
		 */
		if (rowsec_with_check_expr && !hook_with_check_expr_permissive)
		{
			WithCheckOption *wco;

			wco = (WithCheckOption *) makeNode(WithCheckOption);
			wco->kind = commandType == CMD_INSERT ? WCO_RLS_INSERT_CHECK :
				WCO_RLS_UPDATE_CHECK;
			wco->relname = pstrdup(RelationGetRelationName(rel));
			wco->qual = (Node *) rowsec_with_check_expr;
			wco->cascaded = false;
			*withCheckOptions = lappend(*withCheckOptions, wco);
		}
		/* Handle the hook policies, if there are no built-in ones. */
		else if (!rowsec_with_check_expr && hook_with_check_expr_permissive)
		{
			WithCheckOption *wco;

			wco = (WithCheckOption *) makeNode(WithCheckOption);
			wco->kind = commandType == CMD_INSERT ? WCO_RLS_INSERT_CHECK :
				WCO_RLS_UPDATE_CHECK;
			wco->relname = pstrdup(RelationGetRelationName(rel));
			wco->qual = (Node *) hook_with_check_expr_permissive;
			wco->cascaded = false;
			*withCheckOptions = lappend(*withCheckOptions, wco);
		}
		/* Handle the case where there are both. */
		else if (rowsec_with_check_expr && hook_with_check_expr_permissive)
		{
			WithCheckOption *wco;
			List	   *combined_quals = NIL;
			Expr	   *combined_qual_eval;

			combined_quals = lcons(copyObject(rowsec_with_check_expr),
								   combined_quals);

			combined_quals = lcons(copyObject(hook_with_check_expr_permissive),
								   combined_quals);

			combined_qual_eval = makeBoolExpr(OR_EXPR, combined_quals, -1);

			wco = (WithCheckOption *) makeNode(WithCheckOption);
			wco->kind = commandType == CMD_INSERT ? WCO_RLS_INSERT_CHECK :
				WCO_RLS_UPDATE_CHECK;
			wco->relname = pstrdup(RelationGetRelationName(rel));
			wco->qual = (Node *) combined_qual_eval;
			wco->cascaded = false;
			*withCheckOptions = lappend(*withCheckOptions, wco);
		}

		/*
		 * ON CONFLICT DO UPDATE has an RTE that is subject to both INSERT and
		 * UPDATE RLS enforcement.  Those are enforced (as a special, distinct
		 * kind of WCO) on the target tuple.
		 *
		 * Make a second, recursive pass over the RTE for this, gathering
		 * UPDATE-applicable RLS checks/WCOs, and gathering and converting
		 * UPDATE-applicable security quals into WCO_RLS_CONFLICT_CHECK RLS
		 * checks/WCOs.  Finally, these distinct kinds of RLS checks/WCOs are
		 * concatenated with our own INSERT-applicable list.
		 */
		if (root->onConflict && root->onConflict->action == ONCONFLICT_UPDATE &&
			commandType == CMD_INSERT)
		{
			List	   *conflictSecurityQuals = NIL;
			List	   *conflictWCOs = NIL;
			ListCell   *item;
			bool		conflictHasRowSecurity = false;
			bool		conflictHasSublinks = false;

			/* Assume that RTE is target resultRelation */
			get_row_security_policies(root, CMD_UPDATE, rte, rt_index,
									  &conflictSecurityQuals, &conflictWCOs,
									  &conflictHasRowSecurity,
									  &conflictHasSublinks);

			if (conflictHasRowSecurity)
				*hasRowSecurity = true;
			if (conflictHasSublinks)
				*hasSubLinks = true;

			/*
			 * Append WITH CHECK OPTIONs/RLS checks, which should not conflict
			 * between this INSERT and the auxiliary UPDATE
			 */
			*withCheckOptions = list_concat(*withCheckOptions,
											conflictWCOs);

			foreach(item, conflictSecurityQuals)
			{
				Expr	   *conflict_rowsec_expr = (Expr *) lfirst(item);
				WithCheckOption *wco;

				wco = (WithCheckOption *) makeNode(WithCheckOption);

				wco->kind = WCO_RLS_CONFLICT_CHECK;
				wco->relname = pstrdup(RelationGetRelationName(rel));
				wco->qual = (Node *) copyObject(conflict_rowsec_expr);
				wco->cascaded = false;
				*withCheckOptions = lappend(*withCheckOptions, wco);
			}
		}
Exemple #5
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);
  }