#endif lint
#include <mit-copyright.h>
+#include <string.h>
#include "query.h"
#include "mr_server.h"
EXEC SQL INCLUDE sqlca; /* SQL Communications Area */
char stmt_buf[MR_STMTBUF_LEN];
EXEC SQL END DECLARE SECTION;
-char *Argv[16];
+char *Argv[QMAXARGS];
int ingres_errno = 0;
int mr_errcode = 0;
EXEC SQL BEGIN DECLARE SECTION;
int query_timeout = 30;
+char *database = "moira";
EXEC SQL END DECLARE SECTION;
extern char *whoami;
extern FILE *journal;
break;
/* These should never come up unless someone breaks the query table */
case INGRES_NO_CURSOR:
- mr_errcode = MR_INTERNAL;
+ if (mr_errcode != MR_BUSY &&
+ mr_errcode != MR_DEADLOCK)
+ mr_errcode = MR_INTERNAL;
com_err(whoami, 0, "Cursor not opened");
break;
case INGRES_NO_STMT:
int mr_open_database()
{
register int i;
- char *malloc();
MR_SQLDA_T *mr_alloc_SQLDA();
static first_open = 1;
/* open the database */
#ifsql INGRES
- EXEC SQL CONNECT moira;
+ EXEC SQL CONNECT :database;
if(ingres_errno)
return (ingres_errno);
EXEC SQL set lockmode session where level = table, timeout = :query_timeout;
return(mr_errcode);
EXEC SQL SELECT SIZE(signature) INTO :mr_sig_length FROM users WHERE users_id=0; /* Harmless on second open */
+ EXEC SQL COMMIT WORK;
if(ingres_errno)
return(mr_errcode);
register char *c;
register int i;
char *args[4];
- char *index();
c = fmt;
for (i = 0; i < argc; i++) {
register struct valobj *vo;
register int n;
char elem[16];
+#ifdef _DEBUG_MALLOC_INC
+#undef index
+#endif
n = v->objcnt;
vo = v->valobj;
/* Build arguement vector, verify query and arguments */
+int privileged;
+
mr_verify_query(cl, q, argc, argv_ro)
client *cl;
struct query *q;
register int status;
register struct validate *v = q->validate;
register int i;
- register int privileged = 0;
register char *to,*fr,*stop;
+ privileged = 0;
+
/* copy the arguments into a local argv that we can modify */
if (argc >= QMAXARGS)
return(MR_ARGS);
if (status != MR_SUCCESS && status != MR_PERM)
return(status);
if (status == MR_SUCCESS)
- privileged++;
+ return(MR_SUCCESS);
}
return(privileged ? MR_SUCCESS : MR_PERM);
return ((rowcount == 0) ? MR_NO_MATCH : MR_SUCCESS);
}
+char *sqlstrstr(str,pat)
+ char *str;
+ char *pat;
+{
+ register char *p=pat;
+
+ do {
+ if(*str=='\'') { /* Skip over single-quote delimited substrings */
+ while(*++str && (*str!='\''))
+ ;
+ continue;
+ }
+ if(*str==*p) {
+ register char *s;
+ s=str;
+ while(*++p && (*++s==*p))
+ ;
+ if(*p) p=pat; /* failed */
+ }
+ } while(*p && *++str);
+
+ if(!*str) str=NULL;
+ return(str);
+}
+
+void optimize_sql_stmt(buf)
+char *buf;
+{
+ char *point=buf, *pat, *eopat, *esc1, *esc2, *csr;
+
+ for(point=buf; point=sqlstrstr(point,"LIKE"); point++) {
+ /* Now pointing to string "LIKE" */
+
+ /* Look at next word */
+ for(pat=point+4; *pat==' '; pat++) ;
+
+ /* Is it a single-quote delimited string? */
+ if(*pat!='\'') continue;
+
+ /* look for "escape" clause - save escape character */
+ /* 1. Find end of pattern */
+ for(eopat=pat+1; 1; eopat++) {
+ if(*eopat=='\'') {
+ if(eopat[1]=='\'') /* single-quote is self-escaping */
+ eopat++;
+ else
+ break;
+ }
+ }
+
+ /* 2. Look at next word */
+ for(esc1=eopat; *++esc1==' ';) ;
+
+ /* 3. esc1=0 if not "ESCAPE '?'", where the ? may be any character. */
+ if(strncmp(esc1,"ESCAPE",6)) esc1=NULL;
+
+ if(esc1) {
+ for(esc2=esc1+6; *esc2==' '; esc2++) ;
+
+ if(*esc2++!='\'') continue; /* Bad SQL syntax. Skip. */
+ /* esc2 now points at the escape character itself */
+ if(esc2[1]!='\'') continue; /* Weird escape string. Skip. */
+ } else {
+ esc2="\\";
+ }
+
+ /* Is pattern free from special characters? */
+ for(csr=pat; csr<eopat; csr++)
+ if((*csr=='%') || (*csr=='_') || (*csr==*esc2)) break;
+ if(csr!=eopat) continue; /* Uses pattern matching. Skip. */
+
+ /* Optimize the query statement */
+ /* 1. Change "LIKE" to " = " */
+ memcpy(point," = ",4);
+
+ /* 2. Change "ESCAPE" to " " */
+ if(esc1) {
+ memset(esc1,' ',6);
+ /* 3. Change "'*'" to " " */
+ /* (Changes '''' to " ") */
+ if(esc2) memset(esc2-1,' ',(*esc2=='\'')?4:3);
+ }
+ }
+}
+
build_sql_stmt(result_buf,cmd,targetlist,argv,qual)
char *result_buf;
char *cmd;
} else *res++ = *fmt; /* text -> result buffer */
}
*res='\0';
+
+ optimize_sql_stmt(result_buf);
}
do_update(q, argv, qual, action, actarg)
EXEC SQL SELECT km.users_id, km.string_id INTO :u_id, :k_id
FROM krbmap km, strings str
WHERE km.string_id = str.string_id AND str.string = :krbname;
+ EXEC SQL COMMIT WORK;
if (ingres_errno) return(mr_errcode);