]> andersk Git - moira.git/blobdiff - server/qrtn.dc
Canonicalized correlation names.
[moira.git] / server / qrtn.dc
index d3043948794098a4b13834b138ca2fa54df0d215..fdcf02ad0f71ea87db93ea689a29293e8ca89ca3 100644 (file)
@@ -22,6 +22,7 @@ EXEC SQL INCLUDE sqlda;  /* SQL Descriptor Area */
 
 MR_SQLDA_T *SQLDA;
 EXEC SQL BEGIN DECLARE SECTION; 
+int mr_sig_length;
 int idummy;                            
 char cdummy[MR_CDUMMY_LEN];            
 char stmt_buf[MR_STMTBUF_LEN];
@@ -39,37 +40,32 @@ extern FILE *journal;
 
 /** Maybe this should be replaced by something like tytso's sql_error */
 
-#define INGRES_BAD_DATE1 41206
-#define INGRES_BAD_DATE2 40207
-#define INGRES_DEADLOCK 49900
-/*
-#define INGRES_BAD_INT 
-#define INGRES_TIMEOUT 
-#define INGRES_NO_RANGE 
- */
+#define INGRES_BAD_DATE1  40206
+#define INGRES_BAD_DATE2  40207
+#define INGRES_DEADLOCK   49900
 
+#define INGRES_BAD_COLUMN 30110
+#define INGRES_ASGN_ERR   40204
+#define INGRES_NO_CURSOR  30120
+#define INGRES_NO_STMT    30130
 
 /*
- * ingerr: (supposedly) called when Ingres indicates an error.
- * I have not yet been able to get this to work to intercept a
- * database open error.
+ * ingerr: Called when Ingres indicates an error.
  */
 
 void ingerr()
 {
+    EXEC SQL BEGIN DECLARE SECTION; 
+    char err_msg[256];
+    EXEC SQL END DECLARE SECTION;
     ingres_errno = -sqlca.sqlcode;
 
     switch (ingres_errno) {
-/*
- *  case INGRES_BAD_INT:
- *     mr_errcode = MR_INTEGER;
- *     break;
- */
-    case INGRES_BAD_DATE1:
-    case INGRES_BAD_DATE2:
+      case INGRES_BAD_DATE1:
+      case INGRES_BAD_DATE2:
        mr_errcode = MR_DATE;
        break;
-    case INGRES_DEADLOCK:
+      case INGRES_DEADLOCK:
        mr_errcode = MR_DEADLOCK;
        com_err(whoami, 0, "INGRES deadlock detected");
        break;
@@ -79,21 +75,35 @@ void ingerr()
  *     com_err(whoami, 0, "timed out getting lock");
  *     break;
  */
-/*  This probably has no equivalent.
- *  case INGRES_NO_RANGE:
- *     mr_errcode = MR_INGRES_SOFTFAIL;
- *     com_err(whoami, 0, "INGRES missing range statement");
- *     break;
- */
+    case INGRES_NO_CURSOR:
+       mr_errcode = MR_INTERNAL;
+       com_err(whoami, 0, "Cursor not opened");
+       break;
+    case INGRES_NO_STMT:
+       mr_errcode = MR_INTERNAL;
+       com_err(whoami, 0, "Statement not declared");
+       break;
+#if 0
+    /* Taking these out during development lets default: give me the INGRES text */
+    case INGRES_BAD_COLUMN:
+       mr_errcode = MR_INTERNAL;
+       com_err(whoami, 0, "Bad column name in query table");
+        break;
+    case INGRES_ASGN_ERR:
+       mr_errcode = MR_INTERNAL;
+       com_err(whoami, 0, "Error in SQL assignment statement");
+       break;
+#endif
     default:
-       /** Add the INGRES error_text to the alert message ??? **/
        mr_errcode = MR_INGRES_ERR;
-       com_err(whoami, MR_INGRES_ERR, " code %d\n", sqlca.sqlcode);
+       com_err(whoami, MR_INGRES_ERR, " code %d\n", ingres_errno);
+       EXEC SQL INQUIRE_SQL(:err_msg = errortext);
+       com_err(whoami, 0, "SQL error text = %s", err_msg);
        critical_alert("MOIRA", "Moira server encountered INGRES ERROR %d", ingres_errno);
     }
 }
 
-/* This is declarative, not executed.  Applies from here on, in the file */
+/* This is declarative, not executed.  Applies from here on, in this file. */
 EXEC SQL WHENEVER SQLERROR CALL ingerr;
 
 int mr_open_database()
@@ -122,6 +132,8 @@ int mr_open_database()
     /* open the database */
 #ifsql INGRES
     EXEC SQL CONNECT moira;
+    if(ingres_errno) 
+      return (ingres_errno);
     EXEC SQL set lockmode session where level = table, timeout = :query_timeout;
     EXEC SQL set lockmode on capacls where readlock = shared;
     EXEC SQL set lockmode on alias where readlock = shared;
@@ -129,7 +141,15 @@ int mr_open_database()
 #ifsql INFORMIX
     EXEC SQL DATABASE moira
 #endsql
-    return ingres_errno;
+
+    if(ingres_errno) 
+        return(mr_errcode);
+
+    EXEC SQL SELECT SIZE(signature) INTO :mr_sig_length FROM users WHERE users_id=0; /* Harmless on second open */
+    if(ingres_errno)
+        return(mr_errcode);
+
+    return(MR_SUCCESS);
 }
 
 int mr_close_database()
@@ -301,11 +321,15 @@ mr_process_query(cl, name, argc, argv_ro, action, actarg)
            if (status != MR_NO_MATCH) break;
        }
 
+#ifdef NEVER
+       /* This is now done by a valobj, which also fetches the id value */
+
        /* increment id number if necessary */
        if (v->object_id) {
            status = set_next_object_id(v->object_id, q->rtable, 0);
            if (status != MR_SUCCESS) break;
        }
+#endif
 
        /* build "where" clause if needed */
        if (q->qual) {
@@ -322,8 +346,8 @@ mr_process_query(cl, name, argc, argv_ro, action, actarg)
            status = do_append(q, &Argv[q->argc], pqual, action, actarg);
            if (status != MR_SUCCESS) break;
            if (v && v->object_id) {
-               sprintf(qual, "%s.%s = values.value and values.name = '%s'",
-                       q->rtable, v->object_id, v->object_id);
+               sprintf(qual, "%s.%s = %s",q->rtable, v->object_id, 
+                       Argv[q->argc+q->vcnt]);
                incremental_after(q->rtable, qual, argv_ro);
            } else
              incremental_after(q->rtable, pqual, argv_ro);
@@ -506,17 +530,23 @@ mr_verify_query(cl, q, argc, argv_ro)
     register struct validate *v = q->validate;
     register int i;
     register int privileged = 0;
-    int len;
+    register char *to,*fr,*stop;
 
     /* copy the arguments into a local argv that we can modify */
     if (argc >= QMAXARGS)
       return(MR_ARGS);
     for (i = 0; i < argc; i++) {
-       if ((len = strlen(argv_ro[i])) < ARGLEN)
-           strcpy(Argv[i], argv_ro[i]);
-       else
-           return(MR_ARG_TOO_LONG);
-       if (Argv[i][len-1] == '\\')
+       /* Single quotes must be doubled for SQL */
+       for (to=Argv[i], fr=argv_ro[i], stop=to+ARGLEN; (*fr) && (to<stop);) {
+           if(*fr=='\'') 
+             *to++ = *fr;
+           *to++ = *fr++;
+       }
+       if (*fr) 
+         return(MR_ARG_TOO_LONG);
+       *to='\0';
+
+       if (*--to == '\\')
          return(MR_BAD_CHAR);
     }
 
@@ -675,57 +705,22 @@ EXEC SQL END DECLARE SECTION;
            com_err(whoami, MR_NO_MEM, "setting up static argv");
            exit(1);
        }
-       for (i = 0; i < QMAXARGS; i++) {
+       for (i = 0; i < QMAXARGS; i++) {  
            vaddrs[i]=SQLDA->sqlvar[i].sqldata;
        }
     }
 
-/*
- *  if (psort) {
- *      csort = psort;
- *     if (pqual) {
- *         cqual = pqual;
- *          retrieve unique (param (q->tlist, vaddrs)) where cqual
- *                   sort by csort
- *          {
- *              (*action)(q->vcnt, vaddrs, actarg);
- *          }
- *     } else {
- *          retrieve unique (param (q->tlist, vaddrs))
- *                   sort by csort
- *          {
- *              (*action)(q->vcnt, vaddrs, actarg);
- *          }
- *     }
- *  
- *  } else {
- *     if (pqual) {
- *         cqual = pqual;
- *          retrieve unique (param (q->tlist, vaddrs)) where cqual
- *          {
- *              (*action)(q->vcnt, vaddrs, actarg);
- *          }
- *     } else {
- *          retrieve unique (param (q->tlist, vaddrs))
- *          {
- *              (*action)(q->vcnt, vaddrs, actarg);
- *          }
- *     }
- *  }
- */
-
     build_sql_stmt(stmt_buf,"SELECT",q->tlist,vaddrs,pqual);
     if(psort) { strcat(stmt_buf," ORDER BY "); strcat(stmt_buf,psort); }
     EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; 
-    if((mr_errcode=mr_check_SQLDA(SQLDA)) != MR_SUCCESS) 
-      return(mr_errcode);
+    if(sqlca.sqlcode)
+      return(MR_INTERNAL);
     EXEC SQL DECLARE csr001 CURSOR FOR stmt;
     EXEC SQL OPEN csr001;
     rowcount = 0;
     while(1) {
        EXEC SQL FETCH csr001 USING DESCRIPTOR :SQLDA;
        if(sqlca.sqlcode != 0) break;
-       mr_fix_nulls_in_SQLDA(SQLDA);
        (*action)(q->vcnt, vaddrs, actarg);
        rowcount++;
     }
@@ -743,36 +738,37 @@ build_sql_stmt(result_buf,cmd,targetlist,argv,qual)
     char *qual;
 {
     char fmt_buf[MR_STMTBUF_LEN];
-    char tmp_buf[16];
-    char *res=result_buf, *tmp=tmp_buf, *fmt=fmt_buf;
-    int state;
-
-    sprintf(fmt_buf,"%s %s",cmd,targetlist);
-    if(qual) { strcat(fmt_buf," WHERE "); strcat(fmt_buf,qual); }
-
-    for(state=0;*fmt != '\0';fmt++) {
-       switch(state) {
-         case 0:
-           if(*fmt=='%') {                          /* formatting -> tmp */
-               *tmp++ = *fmt;
-               state=1;
-           } else *res++ = *fmt;                      /* text -> res */
-           break;
-         case 1:
-           if((*fmt=='%') && (tmp==tmp_buf+1)) {    /* %% -> % */
-               *res++ = *fmt;           
-               tmp=tmp_buf;
-               state=0;
-           } else if(isalpha(*fmt) && (*fmt!='h') && (*fmt!='l')) {  /* end of formatting */
-               *tmp++ = *fmt;
-               *tmp='\0';
-               tmp=tmp_buf;
-               sprintf(res,tmp_buf,*argv++);        /* print to result buffer */
-               while(*res++) ;
-               state=0;
-           } else *tmp++ = *fmt;    /* keep copying the formatting to tmp */
-           break;
-       }
+    register char *res, *fmt;
+
+    if(qual)
+      sprintf(fmt_buf,"%s %s WHERE %s",cmd,targetlist,qual);
+    else
+      sprintf(fmt_buf,"%s %s",cmd,targetlist);
+
+    for(res=result_buf, fmt=fmt_buf; *fmt; fmt++) {
+       if(*fmt=='%') {
+           if(*++fmt) {
+               switch(*fmt) {                       
+                 case '%':                              /* %% -> % */
+                   *res++ = *fmt;           
+                   break;
+                 case 's':
+                   if(*argv[0]) {
+                       *res='\0';
+                       strcat(res,*argv);
+                       while(*++res) ;
+                   }
+                   argv++;
+                   break;
+                 case 'd':
+                   sprintf(res,"%d",*(int *)*argv++);   /* print to result buffer */
+                   while(*++res) ;
+                   break;
+                 default:                               /* Swallow other %? pairs */
+                   break;
+               }
+           } else break;
+       } else *res++ = *fmt;                            /* text -> result buffer */
     }
     *res='\0';
 }
@@ -838,43 +834,33 @@ set_next_object_id(object, table_name, limit)
     EXEC SQL BEGIN DECLARE SECTION; 
     int value;
     EXEC SQL END DECLARE SECTION;
-    int rowcount=0;
-
+    int starting_value;
+    
     EXEC SQL SELECT value INTO :value FROM numvalues WHERE name = :object;
     if (sqlca.sqlerrd[2] != 1)
        return(MR_NO_ID);
 
-/*
- *  retrieve (exists = any(tbl.name where tbl.name = value)) 
- */
-    sprintf(stmt_buf,"SELECT %s FROM %s WHERE %s=:value",object,table_name,object);  /** Will this work??? */
-    EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; 
-    EXEC SQL DECLARE csr002 CURSOR FOR stmt;
-
-    EXEC SQL OPEN csr002;
-    EXEC SQL FETCH csr002 USING DESCRIPTOR :SQLDA; 
-    if(sqlca.sqlcode == 0) {
-       rowcount++;
-       EXEC SQL FETCH csr002 USING DESCRIPTOR :SQLDA; 
-       if(sqlca.sqlcode == 0) rowcount++;
-    }
-    EXEC SQL CLOSE csr002;
-
-    if (rowcount != 1)
-      return(MR_NO_ID);
+    starting_value=value;
     while (1) { 
-       value++;
-       if (limit && value > MAX_ID_VALUE)      /* Potential infinite loop */
-         value = MIN_ID_VALUE;
-/*
- *     retrieve (exists = any(tbl.name where tbl.name = value)) 
- */
-       
-       /** Does the following work like I think it should ??? */
+       if (limit && value > MAX_ID_VALUE) 
+           value = MIN_ID_VALUE;
+
+       sprintf(stmt_buf,"SELECT %s FROM %s WHERE %s=%d",object,table_name,object,value);  
+       EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; 
+       if(sqlca.sqlcode)
+         return(MR_INTERNAL);
+       EXEC SQL DECLARE csr002 CURSOR FOR stmt;
        EXEC SQL OPEN csr002;
-       EXEC SQL FETCH csr002 USING DESCRIPTOR :SQLDA; 
-       if(sqlca.sqlcode == 100) break;
+       EXEC SQL FETCH csr002 USING DESCRIPTOR :SQLDA;
+       if (sqlca.sqlcode < 0) return(mr_errcode);
+       if (sqlca.sqlcode == 100) break;
+
        EXEC SQL CLOSE csr002;
+       value++;
+       if (limit && value == starting_value) {   
+           com_err(whoami,0,"All id values have been used");
+           return(MR_NO_ID);
+       }
     }
     EXEC SQL CLOSE csr002;
 
This page took 0.03835 seconds and 4 git commands to generate.