* predicate_classify * Classify an expression node as AND-type, OR-type, or neither (an atom). * * If the expression is classified as AND- or OR-type, then *info is filled * in with the functions needed to iterate over its components. * * This function also implements enforcement of MAX_SAOP_ARRAY_SIZE: if a * ScalarArrayOpExpr's array has too many elements, we just classify it as an * a
| 829 | * that would result in wrong proofs, rather than failing to prove anything. |
| 830 | */ |
| 831 | static PredClass |
| 832 | predicate_classify(Node *clause, PredIterInfo info) |
| 833 | { |
| 834 | /* Caller should not pass us NULL, nor a RestrictInfo clause */ |
| 835 | Assert(clause != NULL); |
| 836 | Assert(!IsA(clause, RestrictInfo)); |
| 837 | |
| 838 | /* |
| 839 | * If we see a List, assume it's an implicit-AND list; this is the correct |
| 840 | * semantics for lists of RestrictInfo nodes. |
| 841 | */ |
| 842 | if (IsA(clause, List)) |
| 843 | { |
| 844 | info->startup_fn = list_startup_fn; |
| 845 | info->next_fn = list_next_fn; |
| 846 | info->cleanup_fn = list_cleanup_fn; |
| 847 | return CLASS_AND; |
| 848 | } |
| 849 | |
| 850 | /* Handle normal AND and OR boolean clauses */ |
| 851 | if (is_andclause(clause)) |
| 852 | { |
| 853 | info->startup_fn = boolexpr_startup_fn; |
| 854 | info->next_fn = list_next_fn; |
| 855 | info->cleanup_fn = list_cleanup_fn; |
| 856 | return CLASS_AND; |
| 857 | } |
| 858 | if (is_orclause(clause)) |
| 859 | { |
| 860 | info->startup_fn = boolexpr_startup_fn; |
| 861 | info->next_fn = list_next_fn; |
| 862 | info->cleanup_fn = list_cleanup_fn; |
| 863 | return CLASS_OR; |
| 864 | } |
| 865 | |
| 866 | /* Handle ScalarArrayOpExpr */ |
| 867 | if (IsA(clause, ScalarArrayOpExpr)) |
| 868 | { |
| 869 | ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause; |
| 870 | Node *arraynode = (Node *) lsecond(saop->args); |
| 871 | |
| 872 | /* |
| 873 | * We can break this down into an AND or OR structure, but only if we |
| 874 | * know how to iterate through expressions for the array's elements. |
| 875 | * We can do that if the array operand is a non-null constant or a |
| 876 | * simple ArrayExpr. |
| 877 | */ |
| 878 | if (arraynode && IsA(arraynode, Const) && |
| 879 | !((Const *) arraynode)->constisnull) |
| 880 | { |
| 881 | ArrayType *arrayval; |
| 882 | int nelems; |
| 883 | |
| 884 | arrayval = DatumGetArrayTypeP(((Const *) arraynode)->constvalue); |
| 885 | nelems = ArrayGetNItems(ARR_NDIM(arrayval), ARR_DIMS(arrayval)); |
| 886 | if (nelems <= MAX_SAOP_ARRAY_SIZE) |
| 887 | { |
| 888 | info->startup_fn = arrayconst_startup_fn; |
no test coverage detected