Back to the month index |
Back to the list index
|
cjs@iamerica.net
Sun, 19 Jan 1997 03:46:09 -0600 (CST)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
- Next message: Alvin Oga: "[mSQL] w3-msql Error: Couldn't create temporary table (fwd)"
- Previous message: james sinnamon: "[mSQL] msql.acl entries and html pages"
From: "cjs@iamerica.net" <cjs2895@ns1.zencom.com> Message-Id: <199701190946.DAA11448@zencom.com> Subject: [mSQL] 2.0B3 -- New math operations in updates patch Date: Sun, 19 Jan 1997 03:46:09 -0600 (CST)I've written this simple patch to MSQL 2.0b3 to do -simple- atomic
math operations when updating a record. I've included the ability to
add, subtract, multiply, and divide both ints and reals. This is my
second revision of this path, and it includes a good bit of validation
and will catch dividing by zeros and such. The syntax is pretty
simple, I've barrowed the symbols from C:
+= Addition
-= Subtraction
*= Multiplication
/= Division
Example:
UPDATE table SET val1 += 1, val2 *= 10, val3 /= 5 WHERE val4 = 1
Pretty straightforward, eh?
Here is the patch..
Christopher
diff -rwu msql-2.0-B3/src/msql/errmsg.h msql-2.0-B3.new/src/msql/errmsg.h
--- msql-2.0-B3/src/msql/errmsg.h Mon Jan 13 09:15:52 1997
+++ msql-2.0-B3.new/src/msql/errmsg.h Sun Jan 19 00:45:58 1997
@@ -100,6 +100,8 @@
# define NULL_INDEX_ERROR "Index field \"%s\" cannot be NULL"
# define NULL_COND_ERR "Index condition for \"%s\" cannot be NULL"
+# define DIVIDE_BY_ZERO "Cannot divide field '%s' by zero"
+# define NO_MATH_OPS "Cannot do math ops on field '%s'"
#endif
@@ -178,5 +180,7 @@
# define NULL_INDEX_ERROR "Index field \"%s\" cannot be NULL"
# define NULL_COND_ERR "Index condition for \"%s\" cannot be NULL"
+# define DIVIDE_BY_ZERO "Cannot divide field '%s' by zero"
+# define NO_MATH_OPS "Cannot do math ops on field '%s'"
#endif
Only in msql-2.0-B3.new/src/msql: errmsg.h~
diff -rwu msql-2.0-B3/src/msql/msql_lex.c msql-2.0-B3.new/src/msql/msql_lex.c
--- msql-2.0-B3/src/msql/msql_lex.c Mon Jan 13 09:15:59 1997
+++ msql-2.0-B3.new/src/msql/msql_lex.c Sat Jan 18 18:51:03 1997
@@ -413,6 +413,11 @@
state = 9;
break;
}
+ if (c == '*' || c == '/')
+ {
+ state = 20;
+ break;
+ }
if (iscompop(c))
{
state = 10;
@@ -540,7 +545,7 @@
yyReturn(token(REAL_NUM));
- /* State 9: Incomplete signed number */
+ /* State 9: Incomplete signed number or math op */
CASE(9)
c = yyGet();
if (isdigit(c))
@@ -553,6 +558,13 @@
state = 7;
break;
}
+ if (c == '=')
+ {
+ if (*tokStart == '+')
+ yyReturn(token(PLUSOP));
+ if (*tokStart == '-')
+ yyReturn(token(MINUSOP));
+ }
state = 999;
break;
@@ -673,6 +685,18 @@
yyReturn(token(SYS_VAR));
+ /* State 20: Other math ops */
+ CASE(20)
+ c = yyGet();
+ if (c == '=')
+ {
+ if (*tokStart == '*')
+ yyReturn(token(MULOP));
+ if (*tokStart == '/')
+ yyReturn(token(DIVOP));
+ }
+ state = 999;
+ break;
/* State 999 : Unknown token. Revert to single char */
CASE(999)
yyRevert();
Only in msql-2.0-B3.new/src/msql: msql_lex.c~
diff -rwu msql-2.0-B3/src/msql/msql_priv.h msql-2.0-B3.new/src/msql/msql_priv.h
--- msql-2.0-B3/src/msql/msql_priv.h Mon Jan 13 09:16:00 1997
+++ msql-2.0-B3.new/src/msql/msql_priv.h Sun Jan 19 01:12:41 1997
@@ -68,6 +68,7 @@
ident_t *identVal;
} val;
int type,
+ op,
nullVal,
dataLen;
} val_t;
@@ -91,6 +92,7 @@
funct[NAME_LEN + 1];
val_t *value;
int type,
+ op,
sysvar,
length,
dataLength,
@@ -337,6 +339,13 @@
#define NOT_RLIKE_OP 11
#define NOT_CLIKE_OP 12
+#define PLUS_OP 13
+#define MINUS_OP 14
+#define MUL_OP 15
+#define DIV_OP 16
+#define MATH_NOP 17
+
+
#define NO_BOOL 0
#define AND_BOOL 1
#define OR_BOOL 2
@@ -525,7 +534,7 @@
int checkSysVarCond __ANSI_PROTO((cond_t *));
/* msql_proc.c prototypes */
-int msqlAddField __ANSI_PROTO((ident_t*,int,char *,int,int));
+int msqlAddField __ANSI_PROTO((ident_t*,int,char *,int,int,int));
void msqlProcessQuery ();
void msqlPushCond ();
void msqlAddSubCond __ANSI_PROTO((int));
@@ -534,7 +543,7 @@
void msqlSetDB __ANSI_PROTO((char *));
void msqlSetSelectLimit __ANSI_PROTO((val_t *));
void msqlAddFieldValue __ANSI_PROTO((val_t *));
-void msqlAddCond __ANSI_PROTO((ident_t*,int,val_t*,int));
+int msqlAddCond __ANSI_PROTO((ident_t*,int,val_t*,int));
void msqlAddOrder __ANSI_PROTO((ident_t*,int));
void msqlAddTable __ANSI_PROTO((char*,char*));
void msqlAddIndex __ANSI_PROTO((char*, char*, int, int));
Only in msql-2.0-B3.new/src/msql: msql_priv.h~
diff -rwu msql-2.0-B3/src/msql/msql_proc.c msql-2.0-B3.new/src/msql/msql_proc.c
--- msql-2.0-B3/src/msql/msql_proc.c Mon Jan 13 09:16:00 1997
+++ msql-2.0-B3.new/src/msql/msql_proc.c Sun Jan 19 01:18:17 1997
@@ -475,12 +475,13 @@
** if the field is of type CHAR
*/
-int msqlAddField(ident,type,length,notNull,priKey)
+int msqlAddField(ident,type,length,notNull,priKey,op)
ident_t *ident;
int type;
char *length;
int notNull,
- priKey;
+ priKey,
+ op;
{
register field_t *new;
char *name,
@@ -532,6 +533,7 @@
new->offset = new->null = new->flags =
new->fieldID = new->overflow = 0;
+ new->op = op;
if (table)
{
@@ -687,7 +689,7 @@
** element of a where_clause.
*/
-void msqlAddCond(ident,op,value,bool)
+int msqlAddCond(ident,op,value,bool)
ident_t *ident;
int op;
val_t *value;
@@ -699,6 +701,11 @@
msqlTrace(TRACE_IN,"msqlAddCond()");
+ if ((op < EQ_OP) || (op > NOT_CLIKE_OP)) {
+ free(ident);
+ msqlTrace(TRACE_OUT,"msqlAddCond()");
+ return(-1);
+ }
if (*(ident->seg2))
{
name = ident->seg2;
@@ -733,6 +740,7 @@
}
free(ident);
msqlTrace(TRACE_OUT,"msqlAddCond()");
+ return(0);
}
Only in msql-2.0-B3.new/src/msql: msql_proc.c~
diff -rwu msql-2.0-B3/src/msql/msql_yacc.y msql-2.0-B3.new/src/msql/msql_yacc.y
--- msql-2.0-B3/src/msql/msql_yacc.y Mon Jan 13 09:16:01 1997
+++ msql-2.0-B3.new/src/msql/msql_yacc.y Sun Jan 19 01:17:05 1997
@@ -120,6 +120,11 @@
%token AVL_INDEX
+%token PLUSOP
+%token MINUSOP
+%token MULOP
+%token DIVOP
+
%%
/*
@@ -187,7 +192,7 @@
index_list
: IDENT
{
- if(msqlAddField(msqlCreateIdent(NULL,$1),(int)NULL,0,0,0)<0)
+ if(msqlAddField(msqlCreateIdent(NULL,$1),(int)NULL,0,0,0,MATH_NOP)<0)
{
msqlClean();
return(-1);
@@ -196,7 +201,7 @@
}
| index_list ',' IDENT
{
- if(msqlAddField(msqlCreateIdent(NULL,$3),(int)NULL,0,0,0)<0)
+ if(msqlAddField(msqlCreateIdent(NULL,$3),(int)NULL,0,0,0,MATH_NOP)<0)
{
msqlClean();
return(-1);
@@ -258,7 +263,7 @@
: qual_ident type opt_nullspec opt_keyspec
{
if(msqlAddField((ident_t *)$1,(int)$2,arrayLen,
- notnullflag,keyflag)<0)
+ notnullflag,keyflag,MATH_NOP)<0)
{
msqlClean();
return(-1);
@@ -352,18 +357,18 @@
ident_t *tmp;
tmp = msqlCreateIdent(NULL,"*");
- msqlAddField((ident_t *)tmp,0,0,0,0);
+ msqlAddField((ident_t *)tmp,0,0,0,0,MATH_NOP);
selectWildcard = 1;
}
select_item
: qual_ident
{
- msqlAddField((ident_t *)$1,0,0,0,0);
+ msqlAddField((ident_t *)$1,0,0,0,0,MATH_NOP);
}
| qual_sysvar
{
- msqlAddField((ident_t *)$1,0,0,0,0);
+ msqlAddField((ident_t *)$1,0,0,0,0,MATH_NOP);
}
/*
@@ -426,11 +431,21 @@
cond_list
: cond_list cond_cont cond_field cond_op cond_literal
- { msqlAddCond((ident_t *)$3,(int)$4,(val_t *)$5,(int)$2); }
+ { if (msqlAddCond((ident_t *)$3,(int)$4,(val_t *)$5,(int)$2)<0)
+ {
+ msqlClean();
+ return(-1);
+ }
+ }
| cond_list cond_cont sub_cond
{ msqlAddSubCond((int)$2); }
| cond_field cond_op cond_literal
- { msqlAddCond((ident_t *)$1,(int)$2,(val_t *)$3,NO_BOOL); }
+ { if (msqlAddCond((ident_t *)$1,(int)$2,(val_t *)$3,NO_BOOL)<0)
+ {
+ msqlClean();
+ return(-1);
+ }
+ }
| sub_cond
{ msqlAddSubCond(NO_BOOL); }
@@ -558,7 +573,7 @@
ident_t *tmp;
tmp = msqlCreateIdent(NULL,"*");
- msqlAddField((ident_t *)tmp,0,0,0,0);
+ msqlAddField((ident_t *)tmp,0,0,0,0,MATH_NOP);
$$ = (char *) 1;
}
| '(' fields ')'
@@ -570,11 +585,11 @@
fields
: fields ',' qual_ident
{
- msqlAddField((ident_t *)$3,0,0,0,0);
+ msqlAddField((ident_t *)$3,0,0,0,0,MATH_NOP);
}
| qual_ident
{
- msqlAddField((ident_t *)$1,0,0,0,0);
+ msqlAddField((ident_t *)$1,0,0,0,0,MATH_NOP);
}
@@ -605,10 +620,16 @@
update_list
: update_list ',' qual_ident EQ literal
- { msqlAddField((ident_t *)$3,0,0,0,0);
+ { msqlAddField((ident_t *)$3,0,0,0,0,MATH_NOP);
msqlAddFieldValue((val_t *)$5); }
| qual_ident EQ update_value
- { msqlAddField((ident_t *)$1,0,0,0,0);
+ { msqlAddField((ident_t *)$1,0,0,0,0,MATH_NOP);
+ msqlAddFieldValue((val_t *) $3); }
+ | update_list ',' qual_ident mathop literal
+ { msqlAddField((ident_t *)$3,0,0,0,0,(int)$4);
+ msqlAddFieldValue((val_t *)$5); }
+ | qual_ident mathop update_value
+ { msqlAddField((ident_t *)$1,0,0,0,0,(int)$2);
msqlAddFieldValue((val_t *) $3); }
@@ -617,6 +638,17 @@
{ $$ = $1; }
| qual_sysvar
{ $$ = $1; }
+
+mathop
+ : PLUSOP
+ { $$ = (char *)PLUS_OP; }
+ | MINUSOP
+ { $$ = (char *)MINUS_OP; }
+ | MULOP
+ { $$ = (char *)MUL_OP; }
+ | DIVOP
+ { $$ = (char *)DIV_OP; }
+
/*
** Delete : conditionally delete table entries (or all entries)
Only in msql-2.0-B3.new/src/msql: msql_yacc.y~
diff -rwu msql-2.0-B3/src/msql/table.c msql-2.0-B3.new/src/msql/table.c
--- msql-2.0-B3/src/msql/table.c Mon Jan 13 09:16:15 1997
+++ msql-2.0-B3.new/src/msql/table.c Sun Jan 19 00:53:06 1997
@@ -1321,6 +1321,8 @@
u_char *data,
*cp;
u_int pos;
+ int tmpInt;
+ double tmpReal;
msqlTrace(TRACE_IN,"updateValues()");
data = row->data;
@@ -1336,16 +1338,47 @@
switch(curField->type)
{
case INT_TYPE:
+ switch(curField->op) {
+ case MATH_NOP:
+ tmpInt = curField->value->val.intVal;
+ break;
+ case PLUS_OP:
+ tmpInt = unpackInt32(cp);
+ tmpInt += curField->value->val.intVal;
+ break;
+ case MINUS_OP:
+ tmpInt = unpackInt32(cp);
+ tmpInt -= curField->value->val.intVal;
+ break;
+ case MUL_OP:
+ tmpInt = unpackInt32(cp);
+ tmpInt *= curField->value->val.intVal;
+ break;
+ case DIV_OP:
+ if (curField->value->val.intVal == 0)
+ {
+ sprintf(errMsg,DIVIDE_BY_ZERO,
+ curField->name);
+ return(-1);
+ }
+ tmpInt = unpackInt32(cp);
+ tmpInt /= curField->value->val.intVal;
+ break;
+ }
#ifndef _CRAY
- bcopy4(&(curField->value->val.intVal),
- cp);
+ bcopy4(&tmpInt, cp);
#else
- packInt32(curField->value->val.intVal,
- cp);
+ packInt32(tmpInt, cp);
#endif
break;
case CHAR_TYPE:
+ if (curField->op != MATH_NOP)
+ {
+ sprintf(errMsg,NO_MATH_OPS,
+ curField->name);
+ return(-1);
+ }
length = strlen((char *)
curField->value->val.charVal);
if (length > curField->length)
@@ -1361,6 +1394,12 @@
break;
case TEXT_TYPE:
+ if (curField->op != MATH_NOP)
+ {
+ sprintf(errMsg,NO_MATH_OPS,
+ curField->name);
+ return(-1);
+ }
bcopy(cp + sizeof(int), &pos,
sizeof(u_int));
deleteVarChar(entry, pos);
@@ -1382,8 +1421,34 @@
break;
case REAL_TYPE:
- bcopy8(&(curField->value->val.realVal),
- cp);
+ switch(curField->op) {
+ case MATH_NOP:
+ tmpReal = curField->value->val.realVal;
+ break;
+ case PLUS_OP:
+ bcopy8(cp, (char *)&tmpReal);
+ tmpReal += curField->value->val.realVal;
+ break;
+ case MINUS_OP:
+ bcopy8(cp, (char *)&tmpReal);
+ tmpReal -= curField->value->val.realVal;
+ break;
+ case MUL_OP:
+ bcopy8(cp, (char *)&tmpReal);
+ tmpReal *= curField->value->val.realVal;
+ break;
+ case DIV_OP:
+ if (curField->value->val.realVal == 0)
+ {
+ sprintf(errMsg,DIVIDE_BY_ZERO,
+ curField->name);
+ return(-1);
+ }
+ bcopy8(cp, (char *)&tmpReal);
+ tmpReal /= curField->value->val.realVal;
+ break;
+ }
+ bcopy8(&tmpReal, cp);
break;
}
}
--------------------------------------------------------------------------
To remove yourself from the Mini SQL mailing list send a message containing
"unsubscribe" to "unsubscribe" to msql-list-request@bunyip.com. Send a message containing
"info msql-list" to majordomo@bunyip.com for info on monthly archives of
the list. For more help, mail owner-msql-list@bunyip.com NOT the msql-list!
- Next message: Alvin Oga: "[mSQL] w3-msql Error: Couldn't create temporary table (fwd)"
- Previous message: james sinnamon: "[mSQL] msql.acl entries and html pages"