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; } }
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; }*/ }
/* * 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); }
/* * 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); } }
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); }