1: # include "../ingres.h" 2: # include "../aux.h" 3: # include "../symbol.h" 4: # include "../tree.h" 5: # include "../pipes.h" 6: # include "qrymod.h" 7: 8: /* 9: ** ISSUE -- issue query to rest of system 10: ** 11: ** This function issues a query to the rest of the INGRES system. 12: ** It can deal with true queries (that is, a tree), or with a 13: ** DBU request (which must already be in the pipe). 14: ** 15: ** The sync from below is read, but not passed up; a pointer 16: ** to it (or NULL if none) is returned. 17: ** 18: ** Parameters: 19: ** execid -- the execid to call. 20: ** funcid -- the function to call. 21: ** tree -- NULL -- just sync from below. 22: ** else -- pointer to tree to issue. 23: ** 24: ** Returns: 25: ** The resultcode of the query. 26: ** 27: ** Side Effects: 28: ** A query is executed. 29: ** 30: ** Requires: 31: ** wrpipe, rdpipe 32: ** writeqry 33: ** pipetrwr 34: ** 35: ** Called By: 36: ** main 37: ** qrymod 38: ** 39: ** Compilation Flags: 40: ** none 41: ** 42: ** Trace Flags: 43: ** 13 44: ** 45: ** History: 46: ** 2/14/79 -- version 6.2 released. 47: */ 48: 49: extern struct pipfrmt Outpipe; 50: 51: struct retcode * 52: issue(execid, funcid, tree) 53: char execid; 54: char funcid; 55: QTREE *tree; 56: { 57: register QTREE *t; 58: extern pipetrwr(); 59: static struct retcode rc; 60: register int i; 61: register struct retcode *r; 62: 63: t = tree; 64: r = &rc; 65: 66: # ifdef xQTR2 67: if (tTf(13, 1)) 68: printf("issue:\n"); 69: # endif 70: /* write query tree if given */ 71: if (t != NULL) 72: { 73: wrpipe(P_PRIME, &Outpipe, execid, 0, funcid); 74: writeqry(t, &pipetrwr); 75: wrpipe(P_END, &Outpipe, W_down); 76: } 77: 78: /* sync with below */ 79: # ifdef xQTR2 80: if (tTf(13, 2)) 81: printf("issue: response:\n"); 82: # endif 83: rdpipe(P_PRIME, &Outpipe); 84: i = rdpipe(P_NORM, &Outpipe, R_down, r, sizeof *r); 85: rdpipe(P_SYNC, &Outpipe, R_down); 86: if (i == 0) 87: return (NULL); 88: else 89: return (r); 90: } 91: /* 92: ** ISSUEINVERT -- issue a query, but invert the qualification 93: ** 94: ** This routine is similar to 'issue', except that it issues 95: ** a query with the qualification inverted. The inversion 96: ** (and subsequent tree normalization) is done on a duplicate 97: ** of the tree. 98: ** 99: ** Parameters: 100: ** root -- the root of the tree to issue. 101: ** 102: ** Returns: 103: ** pointer to retcode struct. 104: ** 105: ** Side Effects: 106: ** 'root' is issued. 107: ** 108: ** Requires: 109: ** tree -- to create a 'NOT' node. 110: ** treedup -- to create a copy of the tree. 111: ** trimqlend, norml -- to normalize after inversion. 112: ** issue -- to do the actual issue. 113: ** 114: ** Called By: 115: ** d_integ 116: ** 117: ** Trace Flags: 118: ** none 119: */ 120: 121: struct retcode * 122: issueinvert(root) 123: QTREE *root; 124: { 125: register QTREE *t; 126: extern QTREE *tree(), *treedup(); 127: extern QTREE *trimqlend(), *norml(); 128: register struct retcode *r; 129: extern struct retcode *issue(); 130: 131: /* make duplicate of tree */ 132: t = treedup(root); 133: 134: /* prepend NOT node to qualification */ 135: t->right = tree(NULL, t->right, UOP, 2, opNOT); 136: 137: /* normalize and issue */ 138: t->right = norml(trimqlend(t->right)); 139: r = issue(EXEC_DECOMP, 0, t); 140: 141: # ifdef xQTR3 142: /* check for valid return */ 143: if (r == NULL) 144: syserr("issueinvert: NULL rc"); 145: # endif 146: 147: return (r); 148: } 149: /* 150: ** PIPETRWR -- write tree to W_down pipe 151: ** 152: ** Acts like a 'wrpipe' call, with some arguments included 153: ** implicitly. 154: ** 155: ** Parameters: 156: ** val -- the value to write. 157: ** len -- the length. 158: ** 159: ** Returns: 160: ** same as wrpipe. 161: ** 162: ** Side Effects: 163: ** activity on 'Outpipe'. 164: ** 165: ** Requires: 166: ** wrpipe 167: ** Outpipe -- a primed pipe for writing. 168: ** 169: ** Required By: 170: ** issue. 171: */ 172: 173: pipetrwr(val, len) 174: char *val; 175: int len; 176: { 177: return (wrpipe(P_NORM, &Outpipe, W_down, val, len)); 178: } 179: /* 180: ** NULLSYNC -- send null query to sync Equel program 181: ** 182: ** On a RETRIEVE to terminal, Equel is left reading the data 183: ** pipe by the time we get to this point; on an error (which 184: ** will prevent the running of the original query) we must 185: ** somehow unhang it. The solution is to send a completely 186: ** null query, as so: 187: ** 188: ** ROOT 189: ** / \ 190: ** TREE QLEND 191: ** 192: ** This will cause OVQP to send a sync back to the EQUEL program, 193: ** incuring an incredible amount of overhead in the process 194: ** (but it was his own fault!). 195: ** 196: ** Parameters: 197: ** none 198: ** 199: ** Returns: 200: ** none 201: ** 202: ** Side Effects: 203: ** Space is grabbed from Qbuf. 204: ** A query is sent. 205: ** 206: ** Requires: 207: ** tree() -- to create the relevant nodes. 208: ** issue() -- to send the query. 209: ** 210: ** Called By: 211: ** ferror() 212: ** 213: ** Trace Flags: 214: ** none 215: ** 216: ** Diagnostics: 217: ** none 218: ** 219: ** Syserrs: 220: ** none 221: */ 222: 223: struct retcode * 224: nullsync() 225: { 226: register QTREE *t; 227: extern struct retcode *issue(); 228: register struct retcode *rc; 229: QTREE *tree(); 230: 231: t = tree(tree(NULL, NULL, TREE, 0), tree(NULL, NULL, QLEND, 0), ROOT, 0); 232: rc = issue(EXEC_DECOMP, '0', t); 233: return (rc); 234: }