262 const int *head_resno,
int n_heads)
273 List *qual_list = NIL;
281 if (cq->commandType != CMD_SELECT || cq->setOperations != NULL ||
282 cq->jointree == NULL || cq->hasAggs || cq->havingQual != NULL ||
283 cq->hasWindowFuncs || cq->hasSubLinks || cq->cteList != NIL ||
284 cq->jointree->fromlist == NIL)
287 atom_rti = palloc(list_length(cq->rtable) *
sizeof(Index));
288 atom_relid = palloc(list_length(cq->rtable) *
sizeof(Oid));
289 foreach (lc, cq->jointree->fromlist)
291 &natoms, &qual_list))
295 if (cq->jointree->quals != NULL)
296 qual_list = lappend(qual_list, cq->jointree->quals);
304 for (a = 0; a < natoms; a++) {
305 RangeTblEntry *rte = rt_fetch(atom_rti[a], cq->rtable);
306 maxcols += list_length(rte->eref->colnames);
308 cols = palloc(maxcols *
sizeof(
ColRef));
309 pairs = palloc(2 * (list_length(cq->rtable) * 8 + 64) *
sizeof(
int));
311 for (a = 0; a < natoms; a++) {
312 RangeTblEntry *rte = rt_fetch(atom_rti[a], cq->rtable);
313 AttrNumber attno = 0;
315 foreach (c, rte->eref->colnames) {
316 char *name = strVal(lfirst(c));
320 (void)
colref_get(cols, &ncols, atom_rti[a], attno);
324 foreach (lc, qual_list)
328 for (i = 0; i < npairs; i += 2)
329 uf_union(cols, pairs[i], pairs[i + 1]);
331 root_var = palloc(ncols *
sizeof(
int));
332 for (i = 0; i < ncols; i++)
337 for (h = 0; h < n_heads; h++) {
338 TargetEntry *te = NULL;
342 bool tracked =
false;
344 foreach (tc, cq->targetList) {
345 TargetEntry *t = (TargetEntry *) lfirst(tc);
346 if (t->resno == head_resno[h]) { te = t;
break; }
348 if (te == NULL || te->resjunk)
350 e = (Node *) te->expr;
351 while (IsA(e, RelabelType))
352 e = (Node *) ((RelabelType *) e)->arg;
353 if (!IsA(e, Var) || ((Var *) e)->varlevelsup != 0)
356 for (a = 0; a < natoms; a++)
357 if (atom_rti[a] == hv->varno) { tracked =
true;
break; }
360 node =
colref_get(cols, &ncols, hv->varno, hv->varattno);
362 if (root_var[root] >= 0 && root_var[root] != h)
367 for (i = 0; i < ncols; i++) {
370 root_var[r] = nvars++;
373 appendStringInfo(dbuf,
"{\"n_vars\":%d,\"atoms\":[", nvars);
374 for (a = 0; a < natoms; a++) {
375 RangeTblEntry *rte = rt_fetch(atom_rti[a], cq->rtable);
376 AttrNumber attno = 0;
379 List *elem_colnames = NIL;
382 foreach (c, rte->eref->colnames) {
383 char *name = strVal(lfirst(c));
386 elem_colnames = lappend(elem_colnames, makeString(name));
389 if (a) appendStringInfoChar(dbuf,
',');
390 appendStringInfo(dbuf,
"{\"rel\":%d,\"vars\":[", gidx);
392 foreach (c, rte->eref->colnames) {
393 char *name = strVal(lfirst(c));
398 int node =
colref_get(cols, &ncols, atom_rti[a], attno);
399 int var = root_var[
uf_find(cols, node)];
400 if (!firstv) appendStringInfoChar(dbuf,
',');
401 appendStringInfo(dbuf,
"%d", var);
405 appendStringInfoString(dbuf,
"]}");
407 appendStringInfoString(dbuf,
"]}");
560 bool *all_existential,
561 List **head_var_idx, List **head_exprs)
577 Node *residual = NULL;
579 List *qual_list = NIL;
584 *all_existential =
false;
595 if (q->setOperations != NULL) {
597 if (desc != NULL && all_existential)
598 *all_existential =
true;
605 if (q->commandType != CMD_SELECT ||
606 q->jointree == NULL || q->hasAggs ||
607 q->havingQual != NULL ||
608 q->hasWindowFuncs || q->hasSubLinks || q->cteList != NIL)
617 if (list_length(q->jointree->fromlist) == 1 && q->jointree->quals == NULL) {
618 Node *only = (Node *) linitial(q->jointree->fromlist);
619 if (IsA(only, RangeTblRef)) {
620 Index subrti = ((RangeTblRef *) only)->rtindex;
621 RangeTblEntry *subrte = rt_fetch(subrti, q->rtable);
622 if (subrte->rtekind == RTE_SUBQUERY &&
623 subrte->subquery->setOperations != NULL) {
629 int *head_resno = palloc((list_length(q->targetList) +
630 list_length(q->groupClause)) *
sizeof(
int));
635 if (q->groupClause != NIL) {
637 foreach (gl, q->groupClause) {
638 SortGroupClause *sgc = (SortGroupClause *) lfirst(gl);
639 foreach (tc, q->targetList) {
640 TargetEntry *t = (TargetEntry *) lfirst(tc);
641 if (t->ressortgroupref == sgc->tleSortGroupRef) {
642 cand = lappend(cand, t);
break;
647 foreach (lc, q->targetList) {
648 TargetEntry *t = (TargetEntry *) lfirst(lc);
650 cand = lappend(cand, t);
654 TargetEntry *te = (TargetEntry *) lfirst(lc);
657 TargetEntry *ste = NULL;
659 e = (Node *) te->expr;
660 while (IsA(e, RelabelType))
661 e = (Node *) ((RelabelType *) e)->arg;
662 if (!(IsA(e, Var) && ((Var *) e)->varno == subrti &&
663 ((Var *) e)->varlevelsup == 0)) {
664 if (q->groupClause != NIL)
669 foreach (sc, subrte->subquery->targetList) {
670 TargetEntry *t = (TargetEntry *) lfirst(sc);
671 if (t->resno == v->varattno) { ste = t;
break; }
673 if (ste != NULL && ste->resname != NULL &&
684 bool dup =
false;
int z;
685 for (z = 0; z < n_heads; z++)
686 if (head_resno[z] == v->varattno) { dup =
true;
break; }
689 head_resno[n_heads] = v->varattno;
690 hexprs = lappend(hexprs, e);
694 head_resno, n_heads);
699 *all_existential =
true;
700 }
else if (head_var_idx != NULL) {
703 for (h = 0; h < n_heads; h++)
704 *head_var_idx = lappend_int(*head_var_idx, h);
705 if (head_exprs != NULL)
706 *head_exprs = hexprs;
710 if (subrte->rtekind == RTE_SUBQUERY) {
711 List *sub_idx = NIL, *sub_exprs = NIL;
712 bool sub_all =
false;
716 if (desc == NULL || sub_idx == NIL)
723 foreach (xc, sub_exprs)
724 if (!IsA((Node *) lfirst(xc), Var))
727 if (head_var_idx != NULL) {
730 if (head_exprs != NULL)
732 foreach (lc, q->targetList) {
733 TargetEntry *te = (TargetEntry *) lfirst(lc);
736 TargetEntry *ste = NULL;
737 ListCell *sc, *li, *lx;
742 e = (Node *) te->expr;
743 while (IsA(e, RelabelType))
744 e = (Node *) ((RelabelType *) e)->arg;
745 if (!(IsA(e, Var) && ((Var *) e)->varno == subrti &&
746 ((Var *) e)->varlevelsup == 0))
748 outcol = ((Var *) e)->varattno;
749 foreach (sc, subrte->subquery->targetList) {
750 TargetEntry *t = (TargetEntry *) lfirst(sc);
751 if (t->resno == outcol) { ste = t;
break; }
753 if (ste == NULL || ste->resjunk) { clean =
false;
break; }
754 se = (Node *) ste->expr;
755 while (IsA(se, RelabelType))
756 se = (Node *) ((RelabelType *) se)->arg;
757 if (!IsA(se, Var)) { clean =
false;
break; }
758 forboth (li, sub_idx, lx, sub_exprs) {
759 Var *sv = (Var *) lfirst(lx);
760 if (sv->varno == ((Var *) se)->varno &&
761 sv->varattno == ((Var *) se)->varattno) {
766 if (hv < 0) { clean =
false;
break; }
767 if (!list_member_int(*head_var_idx, hv)) {
768 *head_var_idx = lappend_int(*head_var_idx, hv);
769 if (head_exprs != NULL)
770 *head_exprs = lappend(*head_exprs, e);
775 if (head_exprs != NULL)
780 *all_existential =
false;
788 if (q->jointree->fromlist == NIL)
791 int nrte = list_length(q->rtable);
792 atom_rti = palloc(nrte *
sizeof(Index));
793 atom_relid = palloc(nrte *
sizeof(Oid));
794 atom_filter = palloc(nrte *
sizeof(
char *));
795 atom_scanidx = palloc(nrte *
sizeof(
int));
796 scan_relid = palloc(nrte *
sizeof(Oid));
797 scan_filter = palloc(nrte *
sizeof(
char *));
798 per_atom = palloc0(nrte *
sizeof(List *));
800 foreach (lc, q->jointree->fromlist)
802 &natoms, &qual_list))
807 if (q->jointree->quals != NULL)
808 qual_list = lappend(qual_list, q->jointree->quals);
815 qc_split_quals((Node *) qual_list, list_length(q->rtable), per_atom,
822 for (a = 0; a < natoms; a++) {
823 List *sel = per_atom[atom_rti[a] - 1];
825 atom_filter[a] = NULL;
827 Node *conj = (Node *) make_ands_explicit(sel);
829 conj = copyObject(conj);
830 ChangeVarNodes(conj, atom_rti[a], 1, 0);
831 dpctx = deparse_context_for(get_rel_name(atom_relid[a]), atom_relid[a]);
832 atom_filter[a] = deparse_expression(conj, dpctx,
false,
false);
834 for (i = 0; i < nscan; i++)
835 if (scan_relid[i] == atom_relid[a] &&
836 ((scan_filter[i] == NULL && atom_filter[a] == NULL) ||
837 (scan_filter[i] != NULL && atom_filter[a] != NULL &&
838 strcmp(scan_filter[i], atom_filter[a]) == 0))) { found = i;
break; }
840 scan_relid[nscan] = atom_relid[a];
841 scan_filter[nscan] = atom_filter[a];
844 atom_scanidx[a] = found;
849 for (a = 0; a < natoms; a++) {
850 RangeTblEntry *rte = rt_fetch(atom_rti[a], q->rtable);
851 maxcols += list_length(rte->eref->colnames);
853 cols = palloc(maxcols *
sizeof(
ColRef));
854 pairs = palloc(2 * (list_length(q->rtable) * 8 + 64) *
sizeof(
int));
858 for (a = 0; a < natoms; a++) {
859 RangeTblEntry *rte = rt_fetch(atom_rti[a], q->rtable);
860 AttrNumber attno = 0;
862 foreach (c, rte->eref->colnames) {
863 char *name = strVal(lfirst(c));
867 (void)
colref_get(cols, &ncols, atom_rti[a], attno);
879 foreach (rc, rconj) {
883 pairs[npairs++] =
colref_get(cols, &ncols, lv->varno, lv->varattno);
884 pairs[npairs++] =
colref_get(cols, &ncols, rv->varno, rv->varattno);
887 for (i = 0; i < npairs; i += 2)
888 uf_union(cols, pairs[i], pairs[i + 1]);
893 int *root_var = palloc(ncols *
sizeof(
int));
895 for (i = 0; i < ncols; i++)
897 for (i = 0; i < ncols; i++) {
900 root_var[r] = nvars++;
904 initStringInfo(&buf);
905 appendStringInfo(&buf,
"{\"disjuncts\":[{\"n_vars\":%d,\"atoms\":[", nvars);
906 for (a = 0; a < natoms; a++) {
907 RangeTblEntry *rte = rt_fetch(atom_rti[a], q->rtable);
908 AttrNumber attno = 0;
911 if (a) appendStringInfoChar(&buf,
',');
912 appendStringInfo(&buf,
"{\"rel\":%d,\"vars\":[", atom_scanidx[a]);
913 foreach (c, rte->eref->colnames) {
914 char *name = strVal(lfirst(c));
919 int node =
colref_get(cols, &ncols, atom_rti[a], attno);
920 int var = root_var[
uf_find(cols, node)];
921 if (!firstv) appendStringInfoChar(&buf,
',');
922 appendStringInfo(&buf,
"%d", var);
926 appendStringInfoString(&buf,
"]}");
930 appendStringInfoString(&buf,
"]}],\"relations\":[");
931 for (i = 0; i < nscan; i++) {
932 char *nsp = get_namespace_name(get_rel_namespace(scan_relid[i]));
933 char *rel = get_rel_name(scan_relid[i]);
936 appendStringInfo(&qn,
"%s.%s", quote_identifier(nsp),
937 quote_identifier(rel));
938 if (i) appendStringInfoChar(&buf,
',');
942 appendStringInfoString(&buf,
"],\"rel_where\":[");
943 for (i = 0; i < nscan; i++) {
944 if (i) appendStringInfoChar(&buf,
',');
947 appendStringInfoString(&buf,
"],\"elem_cols\":[");
948 for (i = 0; i < nscan; i++) {
951 RangeTblEntry *rte = NULL;
952 AttrNumber attno = 0;
955 for (a = 0; a < natoms; a++)
956 if (atom_scanidx[a] == i) { rte = rt_fetch(atom_rti[a], q->rtable);
break; }
957 if (i) appendStringInfoChar(&buf,
',');
958 appendStringInfoChar(&buf,
'[');
959 foreach (c, rte->eref->colnames) {
960 char *name = strVal(lfirst(c));
964 if (!firstc) appendStringInfoChar(&buf,
',');
968 appendStringInfoChar(&buf,
']');
970 appendStringInfoString(&buf,
"]}");
982 List *hv = NIL, *hx = NIL;
983 if (q->groupClause != NIL) {
985 foreach (gl, q->groupClause) {
986 SortGroupClause *sgc = (SortGroupClause *) lfirst(gl);
987 TargetEntry *gte = NULL;
993 foreach (tc, q->targetList) {
994 TargetEntry *t = (TargetEntry *) lfirst(tc);
995 if (t->ressortgroupref == sgc->tleSortGroupRef) { gte = t;
break; }
997 if (gte == NULL) { clean =
false;
break; }
998 e = (Node *) gte->expr;
999 while (IsA(e, RelabelType))
1000 e = (Node *) ((RelabelType *) e)->arg;
1010 if (!(IsA(e, Var) && ((Var *) e)->varlevelsup == 0)) {
1011 clean =
false;
break;
1014 node =
colref_get(cols, &ncols, vv->varno, vv->varattno);
1015 var = root_var[
uf_find(cols, node)];
1016 if (!list_member_int(hv, var)) {
1017 hv = lappend_int(hv, var);
1018 hx = lappend(hx, e);
1022 foreach (lc, q->targetList) {
1023 TargetEntry *te = (TargetEntry *) lfirst(lc);
1028 if (te->resname != NULL &&
1031 e = (Node *) te->expr;
1032 while (IsA(e, RelabelType))
1033 e = (Node *) ((RelabelType *) e)->arg;
1038 if (IsA(e, Var) && ((Var *) e)->varlevelsup == 0) {
1039 Var *vv = (Var *) e;
1040 int node =
colref_get(cols, &ncols, vv->varno, vv->varattno);
1041 int var = root_var[
uf_find(cols, node)];
1042 if (!list_member_int(hv, var)) {
1043 hv = lappend_int(hv, var);
1044 hx = lappend(hx, e);
1052 if (head_var_idx != NULL) {
1053 *head_var_idx = clean ? hv : NIL;
1054 if (head_exprs != NULL)
1055 *head_exprs = clean ? hx : NIL;
1059 if (all_existential)
1060 *all_existential = clean && (hv == NIL);