⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interp.c

📁 linux 下用c++ 开发的一个小型数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    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);  }}//// mk_attrnames: converts a list of qualified attributes (<relation,// attribute> pairs) into an array of char pointers so it can be// sent to the appropriate UT or QU function.//// All of the attributes should come from relation relname.  If relname// is NULL, then it checks that all attributes come from the same// relation.//// The first element of the array after the last attribute name is// set to the name of the relation.// // Returns:// 	the length of the list on success ( >= 0 )// 	error code otherwise ( < 0 )//// (Thus, the return code is both the number of attributes in the array,// and the index of the relatin name in the array).//static int mk_attrnames(NODE *list, char *attrnames[], char *relname){  int i;  NODE *temp;  // for each qualified attribute in the list...  for(i = 0; list != NULL && i < MAXATTRS; ++i, list = list->u.LIST.next) {    temp = list->u.LIST.self;    // if relname is NULL, then remember this relname    if (relname == NULL)      relname = temp->u.QUALATTR.relname;    // otherwise, see if the relname matches the remembered relname    else if (strcmp(relname, temp->u.QUALATTR.relname))      return E_INCOMPATIBLE;    // add attribute name to the list    attrnames[i] = list->u.LIST.self->u.QUALATTR.attrname;  }  // if the list is too long then error  if (i == MAXATTRS)    return E_TOOMANYATTRS;  // put the relation name in the last position in the array  attrnames[i] = relname;  return i;}//// mk_qual_attrs: converts a list of qualified attributes (<relation,// attribute> pairs) into an array of REL_ATTRS so it can be sent to// QU_Join.//// All of the attributes must come from either relname1 or relname2.//// Returns:// 	the lengh of the list on success ( >= 0 )// 	error code otherwise//static int mk_qual_attrs(NODE *list, REL_ATTR qual_attrs[],			 char *relname1, char *relname2){  int i;  NODE *attr;  // for each element of the list...  for(i = 0; list != NULL && i < MAXATTRS; ++i, list = list->u.LIST.next) {    attr = list->u.LIST.self;    // if relname != relname 1...    if (strcmp(attr->u.QUALATTR.relname, relname1)) {      // and relname != relname 2, then error      if (strcmp(attr->u.QUALATTR.relname, relname2))	return E_INCOMPATIBLE;    }    // add it to the list    qual_attrs[i].relName = attr->u.QUALATTR.relname;    qual_attrs[i].attrName = attr->u.QUALATTR.attrname;  }  // If the list is too long then error  if (i == MAXATTRS)    return E_TOOMANYATTRS;    return i;}//// mk_attr_descrs: converts a list of attribute descriptors (attribute names,// types, and lengths) to an array of ATTR_DESCR's so it can be sent to// UT_Create.//// Returns:// 	length of the list on success ( >= 0 )// 	error code otherwise//static int mk_attr_descrs(NODE *list, ATTR_DESCR attr_descrs[]){  int i;  int type, len;  NODE *attr;  int errval;  // for each element of the list...  for(i = 0; list != NULL && i < MAXATTRS; ++i, list = list->u.LIST.next) {    attr = list->u.LIST.self;        // interpret the format string    errval = parse_format_string(attr->u.ATTRTYPE.type, &type, &len);    if (errval != E_OK)      return errval;    // add it to the list    attr_descrs[i].attrName = attr->u.ATTRTYPE.attrname;    attr_descrs[i].attrType = type;    attr_descrs[i].attrLen = len;  }    // if the list is too long, then error  if (i == MAXATTRS)    return E_TOOMANYATTRS;    return i;}//// mk_ins_attrs: converts a list of <attribute, value> pairs to an array// of ATTR_VAL's so it can be sent to QU_Insert.//// Returns:// 	length of the list on success ( >= 0 )// 	error code otherwise ( < 0 )//static int mk_ins_attrs(NODE *list, ATTR_VAL ins_attrs[]){  int i, type, len;  NODE *attr;    // add the attributes to the list  for(i = 0; list != NULL && i < MAXATTRS; ++i, list = list->u.LIST.next) {    attr = list->u.LIST.self;        // make sure string attributes aren't too long    type = type_of(attr->u.ATTRVAL.value);    len = length_of(attr->u.ATTRVAL.value);    if (type == STRING && len > MAXSTRINGLEN)      return E_STRINGTOOLONG;        ins_attrs[i].attrName = attr->u.ATTRVAL.attrname;    ins_attrs[i].valType = type;    ins_attrs[i].valLength = len;    ins_attrs[i].value = value_of(attr->u.ATTRVAL.value);  }    // if list is too long then error  if (i == MAXATTRS)    return E_TOOMANYATTRS;    return i;}/*  Re write parse_format_string due to change of NODE.ATTRTYPE*/static int parse_format_string(int format, int *type, int *len){  if (format == ('i'-128)) {    *type = INTEGER;    *len = sizeof(int);    return E_OK;  }  else if (format == ('f'-128)) {    *type = FLOAT;    *len = sizeof(float);    return E_OK;  }  else if ((format<=255)&&(format>=1)) {    *type = STRING;    *len = format;    return E_OK;  }  return E_INVFORMATSTRING;}/*//// parse_format_string: deciphers a format string of the form: x// where x is a type specification (one of `i' INTEGER, `f' FLOAT,// or `s' STRING, and stores the type in *type.//// Returns// 	E_OK on success// 	error code otherwise//static int parse_format_string(char *format_string, int *type, int *len){  int n;  char c;    // extract the components of the format string  n = sscanf(format_string, "%c%d", &c, len);    // if no length given...  if (n == 1) {        switch(c) {    case INTCHAR:      *type = INTEGER;      *len = sizeof(int);      break;    case FLOATCHAR:      *type = FLOAT;      *len = sizeof(float);      break;    case STRCHAR:      *type = STRING;      *len = 1;      break;    default:      return E_INVFORMATSTRING;    }  }  // if both are given, make sure the length is valid  else if (n == 2) {    switch(c) {    case INTCHAR:      *type = INTEGER;      if (*len != sizeof(int))	return E_INVINTSIZE;      break;    case FLOATCHAR:      *type = FLOAT;      if (*len != sizeof(float))	return E_INVFLOATSIZE;      break;    case STRCHAR:      *type = STRING;      break;    default:      return E_INVFORMATSTRING;    }  }  // otherwise it's not a valid format string  else    return E_INVFORMATSTRING;    return E_OK;}*///// type_of: returns the type of a value node//static int type_of(NODE *n){  return n->u.VALUE.type;}//// length_of: returns the length of the value in a value node//static int length_of(NODE *n){  return n->u.VALUE.len;}//// value_of: returns the value of a value node// The caller will get a fresh copy of the value, in string form.// We assume the caller will free() the memory pointed to by the// return value of this function.//static void *value_of(NODE *n){  char *newvalue;  char value[255];    switch(type_of(n)) {  case INTEGER:    sprintf(value, "%d", n->u.VALUE.u.ival);    break;  case FLOAT:    sprintf(value, "%f", n->u.VALUE.u.rval);    break;  case STRING:    sprintf(value, "%s", n->u.VALUE.u.sval);  }  if (!(newvalue = new char [strlen(value)+1])) {    fprintf(stderr, "could not allocate memory\n");    exit(1);  }  strcpy(newvalue, value);  return (void *)newvalue;}//// print_error: prints an error message corresponding to errval//static void print_error(char *errmsg, int errval){  if (errmsg != NULL)    fprintf(stderr, "%s: ", errmsg);  switch(errval) {  case E_OK:    fprintf(ERRFP, "no error\n");    break;  case E_INCOMPATIBLE:    fprintf(ERRFP, "attributes must be from selected relation(s)\n");    break;  case E_TOOMANYATTRS:    fprintf(ERRFP, "too many attributes\n");    break;  case E_NOLENGTH:    fprintf(ERRFP, "length must be specified for STRING attribute\n");    break;  case E_INVINTSIZE:    fprintf(ERRFP, "invalid size for INTEGER attribute (should be %d)\n",	    (int) sizeof(int));    break;  case E_INVFLOATSIZE:    fprintf(ERRFP, "invalid size for FLOAT attribute (should be %d)\n",	    (int) sizeof(float));    break;  case E_INVFORMATSTRING:    fprintf(ERRFP, "invalid format string\n");    break;  case E_INVSTRLEN:    fprintf(ERRFP, "invalid length for string attribute\n");    break;  case E_DUPLICATEATTR:    fprintf(ERRFP, "duplicated attribute name\n");    break;  case E_TOOLONG:    fprintf(stderr, "relation name or attribute name too long\n");    break;  case E_STRINGTOOLONG:    fprintf(stderr, "string attribute too long\n");    break;  default:    fprintf(ERRFP, "unrecognized errval: %d\n", errval);  }}//// quit procedure (makes sure that we exit, even it UT_Quit doesn't)//void quit(void){  UT_Quit();  // if UT_Quit didn't exit, then print a warning and quit  fprintf(stderr, "*** ERROR:  UT_quit failed to exit. ***\n");    exit(1);}static void echo_query(NODE *n){  switch(n->kind) {  case N_QUERY:    printf("select");    if (n->u.QUERY.relname != NULL)      printf(" into %s", n->u.QUERY.relname);    printf(" (");    print_attrnames(n->u.QUERY.attrlist);    printf(")");    print_qual(n->u.QUERY.qual);    printf(";\n");    break;  case N_INSERT:    printf("insert %s (", n->u.INSERT.relname);    print_attrvals(n->u.INSERT.attrlist);    printf(");\n");    break;  case N_DELETE:    printf("delete %s", n->u.DELETE.relname);    print_qual(n->u.DELETE.qual);    printf(";\n");    break;  case N_UPDATE:    printf("update %s", n->u.UPDATE.relname);    print_attrvals(n->u.UPDATE.attrlist);    print_qual(n->u.UPDATE.qual);    printf(";\n");    break;  case N_CREATE:    printf("create %s (", n->u.CREATE.relname);    print_attrdescrs(n->u.CREATE.attrlist);    printf(")");    print_primattr(n->u.CREATE.primattr);    printf(";\n");    break;  case N_DESTROY:    printf("destroy %s;\n", n->u.DESTROY.relname);    break;  case N_BUILD:    printf("buildindex %s(%s);\n", n->u.BUILD.relname, n->u.BUILD.attrname);#if 0    printf("buildindex %s(%s) numbuckets = %d;\n", n->u.BUILD.relname,	   n->u.BUILD.attrname, n->u.BUILD.nbuckets);#endif    break;  case N_REBUILD:    printf("rebuildindex %s(%s) numbuckets = %d;\n", n->u.BUILD.relname,	   n->u.BUILD.attrname, n->u.BUILD.nbuckets);    break;  case N_DROP:    printf("dropindex %s", n->u.DROP.relname);    if (n->u.DROP.attrname != NULL)      printf("(%s)", n->u.DROP.attrname);    printf(";\n");    break;  case N_LOAD:    printf("load %s(\"%s\");\n",	   n->u.LOAD.relname, n->u.LOAD.filename);    break;  case N_PRINT:    printf("print %s;\n", n->u.PRINT.relname);    break;  case N_HELP:    printf("help");    if (n->u.HELP.relname != NULL)      printf(" %s", n->u.HELP.relname);    printf(";\n");    break;  default:                              // so that compiler won't complain    assert(0);  }}static void print_attrnames(NODE *n){  for(; n != NULL; n = n->u.LIST.next) {    print_qualattr(n->u.LIST.self);    if (n->u.LIST.next != NULL)      printf(", ");  }}static void print_attrvals(NODE *n){  NODE *attr;    for(; n != NULL; n = n->u.LIST.next) {    attr = n->u.LIST.self;    printf("%s =", attr->u.ATTRVAL.attrname);    print_val(attr->u.ATTRVAL.value);    if (n->u.LIST.next != NULL)      printf(", ");  }}static void print_attrdescrs(NODE *n){  NODE *attr;  for(; n != NULL; n = n->u.LIST.next) {    attr = n->u.LIST.self;    printf("%s = ", attr->u.ATTRTYPE.attrname);    int format = attr->u.ATTRTYPE.type;    if (format == ('i'-128)) {      printf("int");    }    else if (format == ('f'-128)) {      printf("real");    }    else if ((format<=255)&&(format>=1)) {      printf("char(%d)", attr->u.ATTRTYPE.type);    }    if (n->u.LIST.next != NULL)      printf(", ");  }}static void print_primattr(NODE *n){  if (n == NULL)    return;    printf(" primary %s numbuckets = %d",	 n->u.PRIMATTR.attrname, n->u.PRIMATTR.nbuckets);}static void print_qual(NODE *n){  if (n == NULL)    return;  printf(" where ");  if (n->kind == N_SELECT) {    print_qualattr(n->u.SELECT.selattr);    print_op(n->u.SELECT.op);    print_val(n->u.SELECT.value);  } else {    print_qualattr(n->u.JOIN.joinattr1);    print_op(n->u.JOIN.op);    printf(" ");    print_qualattr(n->u.JOIN.joinattr2);  }}static void print_qualattr(NODE *n){  printf("%s.%s", n->u.QUALATTR.relname, n->u.QUALATTR.attrname);}static void print_op(int op){  switch(op) {  case LT:    printf(" <");    break;  case LTE:    printf(" <=");    break;  case EQ:    printf(" =");    break;  case GT:    printf(" >");    break;  case GTE:    printf(" >=");    break;  case NE:    printf(" <>");    break;  }}static void print_val(NODE *n){  switch(n->u.VALUE.type) {  case INTEGER:    printf(" %d", n->u.VALUE.u.ival);    break;  case FLOAT:    printf(" %f", n->u.VALUE.u.rval);    break;  case STRING:    printf(" \"%s\"", n->u.VALUE.u.sval);    break;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -