bool pgut_send(PGconn* conn, const char *query, int nParams, const char **params) { int res; CHECK_FOR_INTERRUPTS(); /* write query to elog if debug */ if (pgut_echo) echo_query(query, nParams, params); if (conn == NULL) { ereport(ERROR, (errcode(E_PG_COMMAND), errmsg("not connected"))); return false; } if (nParams == 0) res = PQsendQuery(conn, query); else res = PQsendQueryParams(conn, query, nParams, NULL, params, NULL, NULL, 0); if (res != 1) { ereport(ERROR, (errcode(E_PG_COMMAND), errmsg("query failed: %s", PQerrorMessage(conn)), errdetail("query was: %s", query))); return false; } return true; }
PGresult * pgut_execute_elevel(PGconn* conn, const char *query, int nParams, const char **params, int elevel) { PGresult *res; pgutConn *c; CHECK_FOR_INTERRUPTS(); /* write query to elog if debug */ if (pgut_echo) echo_query(query, nParams, params); if (conn == NULL) { ereport(elevel, (errcode(E_PG_COMMAND), errmsg("not connected"))); return NULL; } /* find connection */ pgut_conn_lock(); for (c = pgut_connections; c; c = c->next) if (c->conn == conn) break; pgut_conn_unlock(); if (c) on_before_exec(c); if (nParams == 0) res = PQexec(conn, query); else res = PQexecParams(conn, query, nParams, NULL, params, NULL, NULL, 0); if (c) on_after_exec(c); switch (PQresultStatus(res)) { case PGRES_TUPLES_OK: case PGRES_COMMAND_OK: case PGRES_COPY_IN: break; default: ereport(elevel, (errcode(E_PG_COMMAND), errmsg("query failed: %s", PQerrorMessage(conn)), errdetail("query was: %s", query))); break; } return res; }
/* * interp: interprets parse trees * */ RC interp(NODE *n) { RC errval = 0; /* returned error value */ /* if input not coming from a terminal, then echo the query */ if(!isatty(0)) echo_query(n); switch(n -> kind){ case N_CREATETABLE: /* for CreateTable() */ { int nattrs; AttrInfo attrInfos[MAXATTRS]; /* Make sure relation name isn't too long */ if(strlen(n -> u.CREATETABLE.relname) > MAXNAME){ print_error((char*)"create", E_TOOLONG); break; } /* Make a list of AttrInfos suitable for sending to Create */ nattrs = mk_attr_infos(n -> u.CREATETABLE.attrlist, MAXATTRS, attrInfos); if(nattrs < 0){ print_error((char*)"create", nattrs); break; } /* Make the call to create */ errval = pSmm->CreateTable(n->u.CREATETABLE.relname, nattrs, attrInfos); break; } case N_CREATEINDEX: /* for CreateIndex() */ errval = pSmm->CreateIndex(n->u.CREATEINDEX.relname, n->u.CREATEINDEX.attrname); break; case N_DROPINDEX: /* for DropIndex() */ errval = pSmm->DropIndex(n->u.DROPINDEX.relname, n->u.DROPINDEX.attrname); break; case N_DROPTABLE: /* for DropTable() */ errval = pSmm->DropTable(n->u.DROPTABLE.relname); break; case N_LOAD: /* for Load() */ errval = pSmm->Load(n->u.LOAD.relname, n->u.LOAD.filename); break; case N_SET: /* for Set() */ errval = pSmm->Set(n->u.SET.paramName, n->u.SET.string); break; case N_HELP: /* for Help() */ if (n->u.HELP.relname) errval = pSmm->Help(n->u.HELP.relname); else errval = pSmm->Help(); break; case N_PRINT: /* for Print() */ errval = pSmm->Print(n->u.PRINT.relname); break; case N_QUERY: /* for Query() */ { int nSelAttrs = 0; RelAttr relAttrs[MAXATTRS]; int nRelations = 0; char *relations[MAXATTRS]; int nConditions = 0; Condition conditions[MAXATTRS]; /* Make a list of RelAttrs suitable for sending to Query */ nSelAttrs = mk_rel_attrs(n->u.QUERY.relattrlist, MAXATTRS, relAttrs); if(nSelAttrs < 0){ print_error((char*)"select", nSelAttrs); break; } /* Make a list of relation names suitable for sending to Query */ nRelations = mk_relations(n->u.QUERY.rellist, MAXATTRS, relations); if(nRelations < 0){ print_error((char*)"select", nRelations); break; } /* Make a list of Conditions suitable for sending to Query */ nConditions = mk_conditions(n->u.QUERY.conditionlist, MAXATTRS, conditions); if(nConditions < 0){ print_error((char*)"select", nConditions); break; } /* Make the call to Select */ errval = pQlm->Select(nSelAttrs, relAttrs, nRelations, relations, nConditions, conditions); break; } case N_INSERT: /* for Insert() */ { int nValues = 0; Value values[MAXATTRS]; /* Make a list of Values suitable for sending to Insert */ nValues = mk_values(n->u.INSERT.valuelist, MAXATTRS, values); if(nValues < 0){ print_error((char*)"insert", nValues); break; } /* Make the call to insert */ errval = pQlm->Insert(n->u.INSERT.relname, nValues, values); break; } case N_DELETE: /* for Delete() */ { int nConditions = 0; Condition conditions[MAXATTRS]; /* Make a list of Conditions suitable for sending to delete */ nConditions = mk_conditions(n->u.DELETE.conditionlist, MAXATTRS, conditions); if(nConditions < 0){ print_error((char*)"delete", nConditions); break; } /* Make the call to delete */ errval = pQlm->Delete(n->u.DELETE.relname, nConditions, conditions); break; } case N_UPDATE: /* for Update() */ { RelAttr relAttr; // The RHS can be either a value or an attribute Value rhsValue; RelAttr rhsRelAttr; int bIsValue; int nConditions = 0; Condition conditions[MAXATTRS]; /* Make a RelAttr suitable for sending to Update */ mk_rel_attr(n->u.UPDATE.relattr, relAttr); struct node *rhs = n->u.UPDATE.relorvalue; if (rhs->u.RELATTR_OR_VALUE.relattr) { mk_rel_attr(rhs->u.RELATTR_OR_VALUE.relattr, rhsRelAttr); bIsValue = 0; } else { /* Make a value suitable for sending to update */ mk_value(rhs->u.RELATTR_OR_VALUE.value, rhsValue); bIsValue = 1; } /* Make a list of Conditions suitable for sending to Update */ nConditions = mk_conditions(n->u.UPDATE.conditionlist, MAXATTRS, conditions); if(nConditions < 0){ print_error((char*)"update", nConditions); break; } /* Make the call to update */ errval = pQlm->Update(n->u.UPDATE.relname, relAttr, bIsValue, rhsRelAttr, rhsValue, nConditions, conditions); break; } default: // should never get here break; } return (errval); }
void interp(NODE *n) { int nattrs; // number of attributes int type; // attribute type int len; // attribute length int op; // comparison operator NODE *temp, *temp1, *temp2; // temporary node pointers char *attrname; // temp attribute names void *value; // temp value int nbuckets; // temp number of buckets int errval; // returned error value RelDesc relDesc; Status status; int attrCnt, i, j; AttrDesc *attrs; string resultName; static int counter = 0; // if input not coming from a terminal, then echo the query if (!isatty(0)) echo_query(n); switch(n->kind) { case N_QUERY: // First check if the result relation is specified if (n->u.QUERY.relname) { resultName = n->u.QUERY.relname; // Check if the result relation exists. status = attrCat->getRelInfo(resultName, attrCnt, attrs); if (status != OK && status != RELNOTFOUND) { error.print(status); return; } } else { resultName = "Tmp_Minirel_Result"; status = relCat->getInfo(resultName, relDesc); if (status != OK && status != RELNOTFOUND) { error.print(status); return; } if (status == OK) { error.print(TMP_RES_EXISTS); return; } } // if no qualification then this is a simple select temp = n->u.QUERY.qual; if (temp == NULL) { // make a list of attribute names suitable for passing to select nattrs = mk_attrnames(temp1 = n->u.QUERY.attrlist, names, NULL); if (nattrs < 0) { print_error("select", nattrs); break; } for(int acnt = 0; acnt < nattrs; acnt++) { strcpy(attrList[acnt].relName, names[nattrs]); strcpy(attrList[acnt].attrName, names[acnt]); attrList[acnt].attrType = -1; attrList[acnt].attrLen = -1; attrList[acnt].attrValue = NULL; } if (status == RELNOTFOUND) { // Create the result relation attrInfo *createAttrInfo = new attrInfo[nattrs]; for (i = 0; i < nattrs; i++) { AttrDesc attrDesc; strcpy(createAttrInfo[i].relName, resultName.c_str()); strcpy(createAttrInfo[i].attrName, attrList[i].attrName); status = attrCat->getInfo(attrList[i].relName, attrList[i].attrName, attrDesc); if (status != OK) { error.print(status); return; } createAttrInfo[i].attrType = attrDesc.attrType; createAttrInfo[i].attrLen = attrDesc.attrLen; } status = relCat->createRel(resultName, nattrs, createAttrInfo); delete []createAttrInfo; if (status != OK) { error.print(status); return; } } else { // Check to see that the attribute types match if (nattrs != attrCnt) { error.print(ATTRTYPEMISMATCH); return; } for (i = 0; i < nattrs; i++) { AttrDesc attrDesc; status = attrCat->getInfo(attrList[i].relName, attrList[i].attrName, attrDesc); if (status != OK) { error.print(status); return; } if (attrDesc.attrType != attrs[i].attrType || attrDesc.attrLen != attrs[i].attrLen) { error.print(ATTRTYPEMISMATCH); return; } } free(attrs); } // make the call to QU_Select errval = QU_Select(resultName, nattrs, attrList, NULL, (Operator)0, NULL); if (errval != OK) error.print((Status)errval); } // if qual is `attr op value' then this is a regular select else if (temp->kind == N_SELECT) { temp1 = temp->u.SELECT.selattr; // make a list of attribute names suitable for passing to select nattrs = mk_attrnames(n->u.QUERY.attrlist, names, temp1->u.QUALATTR.relname); if (nattrs < 0) { print_error("select", nattrs); break; } for(int acnt = 0; acnt < nattrs; acnt++) { strcpy(attrList[acnt].relName, names[nattrs]); strcpy(attrList[acnt].attrName, names[acnt]); attrList[acnt].attrType = -1; attrList[acnt].attrLen = -1; attrList[acnt].attrValue = NULL; } strcpy(attr1.relName, names[nattrs]); strcpy(attr1.attrName, temp1->u.QUALATTR.attrname); attr1.attrType = type_of(temp->u.SELECT.value); attr1.attrLen = -1; attr1.attrValue = (char *)value_of(temp->u.SELECT.value); if (status == RELNOTFOUND) { // Create the result relation attrInfo *createAttrInfo = new attrInfo[nattrs]; for (i = 0; i < nattrs; i++) { AttrDesc attrDesc; strcpy(createAttrInfo[i].relName, resultName.c_str()); strcpy(createAttrInfo[i].attrName, attrList[i].attrName); status = attrCat->getInfo(attrList[i].relName, attrList[i].attrName, attrDesc); if (status != OK) { error.print(status); return; } createAttrInfo[i].attrType = attrDesc.attrType; createAttrInfo[i].attrLen = attrDesc.attrLen; } status = relCat->createRel(resultName, nattrs, createAttrInfo); delete []createAttrInfo; if (status != OK) { error.print(status); return; } } else { // Check to see that the attribute types match if (nattrs != attrCnt) { error.print(ATTRTYPEMISMATCH); return; } for (i = 0; i < nattrs; i++) { AttrDesc attrDesc; status = attrCat->getInfo(attrList[i].relName, attrList[i].attrName, attrDesc); if (status != OK) { error.print(status); return; } if (attrDesc.attrType != attrs[i].attrType || attrDesc.attrLen != attrs[i].attrLen) { error.print(ATTRTYPEMISMATCH); return; } } free(attrs); } // make the call to QU_Select char * tmpValue = (char *)value_of(temp->u.SELECT.value); errval = QU_Select(resultName, nattrs, attrList, &attr1, (Operator)temp->u.SELECT.op, tmpValue); delete [] tmpValue; delete [] attr1.attrValue; if (errval != OK) error.print((Status)errval); } // if qual is `attr1 op attr2' then this is a join else { temp1 = temp->u.JOIN.joinattr1; temp2 = temp->u.JOIN.joinattr2; // make an attribute list suitable for passing to join nattrs = mk_qual_attrs(n->u.QUERY.attrlist, qual_attrs, temp1->u.QUALATTR.relname, temp2->u.QUALATTR.relname); if (nattrs < 0) { print_error("select", nattrs); break; } // set up the joined attributes to be passed to Join qual_attrs[nattrs].relName = temp1->u.QUALATTR.relname; qual_attrs[nattrs].attrName = temp1->u.QUALATTR.attrname; qual_attrs[nattrs + 1].relName = temp2->u.QUALATTR.relname; qual_attrs[nattrs + 1].attrName = temp2->u.QUALATTR.attrname; for(int acnt = 0; acnt < nattrs; acnt++) { strcpy(attrList[acnt].relName, qual_attrs[acnt].relName); strcpy(attrList[acnt].attrName, qual_attrs[acnt].attrName); attrList[acnt].attrType = -1; attrList[acnt].attrLen = -1; attrList[acnt].attrValue = NULL; } strcpy(attr1.relName, qual_attrs[nattrs].relName); strcpy(attr1.attrName, qual_attrs[nattrs].attrName); attr1.attrType = -1; attr1.attrLen = -1; attr1.attrValue = NULL; strcpy(attr2.relName, qual_attrs[nattrs+1].relName); strcpy(attr2.attrName, qual_attrs[nattrs+1].attrName); attr2.attrType = -1; attr2.attrLen = -1; attr2.attrValue = NULL; if (status == RELNOTFOUND) { // Create the result relation attrInfo *createAttrInfo = new attrInfo[nattrs]; for (i = 0; i < nattrs; i++) { AttrDesc attrDesc; strcpy(createAttrInfo[i].relName, resultName.c_str()); // Check if there is another attribute with same name for (j = 0; j < i; j++) if (!strcmp(createAttrInfo[j].attrName, attrList[i].attrName)) break; strcpy(createAttrInfo[i].attrName, attrList[i].attrName); if (j != i) sprintf(createAttrInfo[i].attrName, "%s_%d", createAttrInfo[i].attrName, counter++); status = attrCat->getInfo(attrList[i].relName, attrList[i].attrName, attrDesc); if (status != OK) { error.print(status); return; } createAttrInfo[i].attrType = attrDesc.attrType; createAttrInfo[i].attrLen = attrDesc.attrLen; } status = relCat->createRel(resultName, nattrs, createAttrInfo); delete []createAttrInfo; if (status != OK) { error.print(status); return; } } else { // Check to see that the attribute types match if (nattrs != attrCnt) { error.print(ATTRTYPEMISMATCH); return; } for (i = 0; i < nattrs; i++) { AttrDesc attrDesc; status = attrCat->getInfo(attrList[i].relName, attrList[i].attrName, attrDesc); if (status != OK) { error.print(status); return; } if (attrDesc.attrType != attrs[i].attrType || attrDesc.attrLen != attrs[i].attrLen) { error.print(ATTRTYPEMISMATCH); return; } } free(attrs); } // make the call to QU_Join errval = QU_Join(resultName, nattrs, attrList, &attr1, (Operator)temp->u.JOIN.op, &attr2); if (errval != OK) error.print((Status)errval); } if (resultName == string( "Tmp_Minirel_Result")) { // Print the contents of the result relation and destroy it status = UT_Print(resultName); if (status != OK) error.print(status); status = relCat->destroyRel(resultName); if (status != OK) error.print(status); } break; case N_INSERT: // make attribute and value list to be passed to QU_Insert nattrs = mk_ins_attrs(n->u.INSERT.attrlist, ins_attrs); if (nattrs < 0) { print_error("insert", nattrs); break; } // make the call to QU_Insert int acnt; for(acnt = 0; acnt < nattrs; acnt++) { strcpy(attrList[acnt].relName, n->u.INSERT.relname); strcpy(attrList[acnt].attrName, ins_attrs[acnt].attrName); attrList[acnt].attrType = (Datatype)ins_attrs[acnt].valType; attrList[acnt].attrLen = -1; attrList[acnt].attrValue = ins_attrs[acnt].value; } errval = QU_Insert(n->u.INSERT.relname, nattrs, attrList); for (acnt = 0; acnt < nattrs; acnt++) delete [] attrList[acnt].attrValue; if (errval != OK) error.print((Status)errval); break; case N_DELETE: // set up the name of deletion relation qual_attrs[0].relName = n->u.DELETE.relname; // if qualification given... if ((temp1 = n->u.DELETE.qual) != NULL) { // qualification must be a select, not a join if (temp1->kind != N_SELECT) { cerr << "Syntax Error" << endl; break; } temp2 = temp1->u.SELECT.selattr; /* // make sure attribute in qualification is from deletion rel if (strcmp(n->u.DELETE.relname, temp2->u.QUALATTR.relname)) { print_error("delete", E_INCOMPATIBLE); break; } */ // set up qualification attrname = temp2->u.QUALATTR.attrname; op = temp1->u.SELECT.op; type = type_of(temp1->u.SELECT.value); len = length_of(temp1->u.SELECT.value); value = value_of(temp1->u.SELECT.value); } // otherwise, set up for no qualification else { attrname = NULL; op = (Operator)0; type = 0; len = 0; value = NULL; } // make the call to QU_Delete if (attrname) errval = QU_Delete(n -> u.DELETE.relname, attrname, (Operator)op, (Datatype)type, (char *)value); else errval = QU_Delete(n -> u.DELETE.relname, "", (Operator)op, (Datatype)type, (char *)value); delete [] value; if (errval != OK) error.print((Status)errval); break; case N_CREATE: // make a list of ATTR_DESCRS suitable for sending to UT_Create nattrs = mk_attr_descrs(n->u.CREATE.attrlist, attr_descrs); if (nattrs < 0) { print_error("create", nattrs); break; } // get info about primary attribute, if there is one if ((temp = n->u.CREATE.primattr) == NULL) { attrname = NULL; nbuckets = 1; } else { attrname = temp->u.PRIMATTR.attrname; nbuckets = temp->u.PRIMATTR.nbuckets; } for(acnt = 0; acnt < nattrs; acnt++) { strcpy(attrList[acnt].relName, n -> u.CREATE.relname); strcpy(attrList[acnt].attrName, attr_descrs[acnt].attrName); attrList[acnt].attrType = attr_descrs[acnt].attrType; attrList[acnt].attrLen = attr_descrs[acnt].attrLen; attrList[acnt].attrValue = NULL; } // make the call to UT_Create errval = relCat->createRel(n -> u.CREATE.relname, nattrs, attrList); if (errval != OK) error.print((Status)errval); break; case N_DESTROY: errval = relCat->destroyRel(n -> u.DESTROY.relname); if (errval != OK) error.print((Status)errval); break; case N_LOAD: errval = UT_Load(n -> u.LOAD.relname, n -> u.LOAD.filename); if (errval != OK) error.print((Status)errval); break; case N_PRINT: errval = UT_Print(n -> u.PRINT.relname); if (errval != OK) error.print((Status)errval); break; case N_HELP: if (n -> u.HELP.relname) errval = relCat->help(n -> u.HELP.relname); else errval = relCat->help(""); if (errval != OK) error.print((Status)errval); break; default: // so that compiler won't complain assert(0); } }