Category : C Source Code
Archive   : SQLVER1.ZIP
Filename : PREDICAT.C

 
Output of file : PREDICAT.C contained in archive : SQLVER1.ZIP
#ifndef COMPILE
#include "C:\LANGUAGE\C\TURBO.C\40.570\DEFS.H"
#endif

/* */
/***************************************************************************/
/*
int getspredicate( )
-This routine reads the predicate clause for the DELETE, UPDATE and
SELECT commands. The criteria can be based on one of the following:

constantvalue attribute
attribute constantvalue
attribute attribute

where:
-attribute is a field in a table.
-constantvalue is either a string beginning and ending
with either ' or ". Or it can be a number.
-Operator can be: ~=,=,>=,<=,>,<

After the criteria, and "AND", an "OR", or a semicolon is expected.

Calls:
------
-gettype ( );
-getvalue( );
-scanner ( );
Called By:
----------
-delete( );
-select( );
-update( );
*/
int getspredicate(predicate,attributes,tables)
char *predicate;
struct LIST *attributes,
*tables;
{
strcpy(predicate,"");
while(TRUE)
{
char string[128] = "";
int value = 0,
constant = 0,
type = 0,
type1 = 0;

/* get the first constant or attribute name */
if ((value = getvalue(string,attributes,tables)) != 0) return(value);
if ((type = gettype(string,attributes)) == -1) return(-20);

/* determine if first string is a constant */
if((isdigit(string[0])) || (string[0] == '\'')) constant = 1;
strcat(string,",");
strcat(predicate,string);

/* get the operator */
if (scanner(string) == 0) return(-25);
strcat(string,",");
strcat(predicate,string);

/* get the second constant or attribute name */
if ((value = getvalue(string,attributes,tables)) != 0) return(value);
if ((type1 = gettype(string,attributes)) == -1) return(-20);

/* insure that both input strings have the same data type */
if (type != type1) return(-28);

/*
determine if second string is a constant. if it is then the
first one cannot. why compare one constant value to another !
*/
if(((isdigit(string[0])) || (string[0] == '\'')) && constant) return(-12);

strcat(string,",");
strcat(predicate,string);

/* get "AND", "OR", or ";" */
value = scanner(string);
if ((value != 1) && (value != 8) && (value != -1)) return(-6);
if (value == -1) break;

strcat(string,",");
strcat(predicate,string);
}
return(0);
}

/* */
/***************************************************************************/
/*
int getvalue( )
-This routine retrieves either a string, a number or a attribute name
from the commandline. An attribute that is read from the commandline
is qualified with it's table's name if it has not been done.

Calls:
------
-readfield ( );
-readnumber( );
-readstring( );

Called By:
----------
-getspredicate( );

*/
int getvalue(string,attributes,tables)
char *string;
struct LIST *attributes,
*tables;
{
char ch = NULL;
notspace( );
ch = getc(stdin);
ungetc(ch,stdin);
strcpy(string,"");

if (isdigit(ch) || (ch == '-')) return(readnumber(string));
if ((ch == '\'') || (ch == '\"')) return(readstring(string));
if (isalpha(ch)) return(readfield(string,attributes,tables));
return(-1);
}

/* */
/***************************************************************************/
/*
int readnumber( )
-This routine reads a number from the command line as a string.

Calls:
------
-None

Called By:
----------
-getvalue( );

*/
int readnumber(string)
char *string;
{
char *ch = string;
*ch++ = getc(stdin);
while(isdigit(*ch = getc(stdin))) *ch++;

if (!(isspace(*ch)) &&
(*ch != ';') &&
(*ch != '~') &&
(*ch != '=') &&
(*ch != '>') &&
(*ch != '<')) return(-17);

ungetc(*ch,stdin);
*ch = NULL;
return(0);
}

/* */
/***************************************************************************/
/*
int readstring( )
-This routine reads a string from the commandline. The string is
delimited with ' or " at the beginning and end of the string.

Calls:
------
-None

Called By:
----------
-getvalue( );

*/
int readstring(string)
char *string;
{
char *ch = string;
strcpy(ch,"\'");
getc(stdin);
*ch++;
while((*ch = getc(stdin)) != 0x27 && (*ch != '"') && (*ch != 0x0D) && (*ch != 0x0A)) *ch++;
if (*ch == 0x0D || *ch == 0x0A) return(-15);
*ch=NULL;
strcat(ch,"\'");
return(0);
}

/* */
/***************************************************************************/
/*
int readfield( )
-This routine reads an attribute name from the commandline. Then it
determines if it is a legal attribute. If necessary, it will
qualify the attribute name with the first table name that has an
attribute with that name.

Calls:
------
-scanner( );

Called By:
----------
-getvalue( );
*/
int readfield(attribute,attributes,tables)
char *attribute;
struct LIST *attributes,
*tables;
{
struct LIST *pointer = attributes;
scanner(attribute);

/* determine if attribute is in the table. may already be qualified */
while(pointer)
if (strcmp(pointer->data.attribute,attribute) == 0)
return(0);
else
pointer = pointer->rlist;

/* determine if attribute is in the table. qualify the attribute as required */
while(tables)
{
char *ch = NULL,
string[128] = "";

strcpy(string,tables->data.attribute);
ch = string;
while(*ch++ != '.');
*--ch = NULL;
strcat(string,".");
strcat(string,attribute);
pointer = attributes;

while(pointer)
if (strcmp(pointer->data.attribute,string) == 0)
{
strcpy(attribute,string);
return(0);
}
else
pointer = pointer->rlist;

tables = tables->rlist;
}

return(-20); /* attribute is not found */

}

/* */
/***************************************************************************/
/*
int gettype( )
-This routine retrieves the correct data type of a string. It will
search through a list of attributes if required to determine what
type the attribute is.

Calls:
------
-None

Called By:
----------
-getspredicate( );

*/
int gettype(string,attributes)
char *string;
struct LIST *attributes;
{
int type = -1;

if (isdigit(string[0]) || (string[0] == '-')) return(1);
if ((string[0] == '\'') || (string[0] == '\"')) return(0);

while(attributes)
if (strcmp(string,attributes->data.attribute) == 0)
return(attributes->data.type);
else
attributes = attributes->rlist;

return(type);
}

/* */
/***************************************************************************/
/*
int checkdata( );
-This routine compares two different DATA values.

Calls:
------
-None

Called By:
----------
-checktuple( );

*/
int checkdata(value,value1)
struct DATA value,
value1;
{
int evaluate = 0;
if (value.type == 0)
{
int length = 0;
/*
if both values are attributes then their respective strings
cannot be padded with blanks because the length of each string
is static and is determined when the table is created. Therefore
since they might different lengths they should be treated
as different data structures.
*/
if (value.order && value1.order) value.order = value1.order = 0;

/*
below, it must be determined which value is an attribute and
which value is a constant. the constant must be padded with
spaces to the same length as the attributes. This will make
the string comparison possible so the user will not have to
always enter a constant that has the exact length as the
attribute that it is being compared with.
*/

if(value.order)
{
value1.attribute[strlen(value1.attribute) - 1] = '\0';
for (length = strlen(value1.attribute); length <= value.length;length++)
value1.attribute[length] = ' ';
value1.attribute[value.length+1] = '\0';
strcat(value1.attribute,"\'");
}
else
if (value1.order)
{
value.attribute[strlen(value.attribute) - 1] = '\0';
for (length = strlen(value.attribute); length <= value1.length;length++)
value.attribute[length] = ' ';
value.attribute[value1.length+1] = '\0';
strcat(value.attribute,"\'");
}

evaluate = strcmp(value.attribute,value1.attribute);
}
else
if (value.value == value1.value)
evaluate = 0;
else
if (value.value > value1.value)
evaluate = 1;
else
evaluate = -1;
return(evaluate);
}


/* */
/****************************************************************************/
/*
char *getdata( )
-This routine retrieves either a constant or the value of a attribute
that was provided in the predicate clause for the UPDATE, DELETE,
and SELECT commands.

Calls:
------
-getstring( );

Called By:
----------
-checktuple( );

*/
char *getdata(attribute,tuple,data,ch)
struct LIST *attribute,
*tuple;
struct DATA *data;
char *ch;

{
ch = getstring(data->attribute,ch);
data->order = data->type = 0;

if (isdigit(data->attribute[0]) || (data->attribute[0] == '-'))
{
data->value = atol(data->attribute);
data->type = 1;
return(ch);
}

if (data->attribute[0] == '\'') return(ch);

/* mark as being an attribute. this will be used in checkdata( ); */
data->order = 1;

/* find out which attribute in the tuple this data element is.*/
while(attribute)
{
if (strcmp(attribute->data.attribute,data->attribute) == 0) break;
attribute = attribute->rlist;
tuple = tuple->rlist;
}

data->type = attribute->data.type;

if(data->type)
data->value = tuple->data.value;
else
{
data->length = attribute->data.length;
strcpy(data->attribute,"\'");
strcat(data->attribute,tuple->data.attribute);
strcat(data->attribute,"\'");
}
return(ch);
}

/* */
/****************************************************************************/
/*
char *getstring( )
-This routine is used to remove a substring from a string. Each substring
is delimited with a comma.

Calls:
------
-None

Called By:
----------
-getdata ( );
-checktuple ( );

*/
char *getstring(string,ch)
char *string,
*ch;
{

*string = NULL;

while((*string++ = *ch++) != ',');
*--string = NULL;

return(ch);

}

/* */
/****************************************************************************/
/*

int checktuple( );

-This routine is used to see if a certain condition has been met.
It parses a predicate from left to right. "AND" and "OR" can both
be handled.

Calls:
------
-checkcondition( );
-checkdata ( );
-checktuple ( );
-getdata ( );
-getstring ( );

Called By:
----------
-delete ( );
-jointables ( );
-makedistinct( );
-makeview ( );
-printfile ( );
-reordertable( );
-update ( );

*/
int checktuple(tuplelist,list,predicate)
struct LIST *tuplelist,
*list;
char *predicate;

{

char *ch = predicate;

int true = 0,
lastand = 1;

if (strcmp(predicate,"") == 0) return(1); /* No predicate to evaluate */

while(*ch)
{
struct DATA data,
data1;

char compare[4] = "", /* for comparison operator */
andor[4] = ""; /* for AND's and OR's */

int comp = 0,
evaluate = 0;

ch = getdata(list,tuplelist,&data,ch); /* get first data item */
ch = getstring(compare,ch); /* get operator */
comp = checkcondition(compare); /* determine comparison value */
ch = getdata(list,tuplelist,&data1,ch);/* get second data item */

/* determine relationship between both data items */
evaluate = checkdata(data,data1);

switch(comp)
{
case 1: if (evaluate == 0) true = 1 & lastand; /* '=' */
break;
case 2: if (evaluate > 0) true = 1 & lastand; /* '>' */
break;
case 3: if (evaluate < 0) true = 1 & lastand; /* '<' */
break;
case 4: if (evaluate >= 0) true = 1 & lastand; /* '>=' */
break;
case 5: if (evaluate <= 0) true = 1 & lastand; /* '<=' */
break;
case 6: if (evaluate != 0) true = 1 & lastand; /* '~=' */
}

if (*ch)
{
ch = getstring(andor,ch);
if (strcmp(andor,"AND") == 0)
{
true &= checktuple(tuplelist,list,ch);
if (!(true)) lastand = 0;
}
else
{
true |= checktuple(tuplelist,list,ch);
lastand = 1;
}
}
}
return(true);
}


/* */
/****************************************************************************/


  3 Responses to “Category : C Source Code
Archive   : SQLVER1.ZIP
Filename : PREDICAT.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/