aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/odbc/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/odbc/parse.c')
-rw-r--r--src/interfaces/odbc/parse.c205
1 files changed, 121 insertions, 84 deletions
diff --git a/src/interfaces/odbc/parse.c b/src/interfaces/odbc/parse.c
index 6c583b0a056..8916db2072d 100644
--- a/src/interfaces/odbc/parse.c
+++ b/src/interfaces/odbc/parse.c
@@ -34,6 +34,7 @@
#include "connection.h"
#include "qresult.h"
#include "pgtypes.h"
+#include "pgapifunc.h"
#ifdef MULTIBYTE
#include "multibyte.h"
@@ -75,7 +76,7 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu
i++;
}
- if (s[0] == '\0')
+ if (s[i] == '\0')
{
token[0] = '\0';
return NULL;
@@ -92,6 +93,13 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu
while (!isspace((unsigned char) s[i]) && s[i] != ',' &&
s[i] != '\0' && out != smax)
{
+#ifdef MULTIBYTE
+ if (multibyte_char_check(s[i]) != 0)
+ {
+ token[out++] = s[i++];
+ continue;
+ }
+#endif
/* Handle quoted stuff */
if (out == 0 && (s[i] == '\"' || s[i] == '\''))
{
@@ -110,15 +118,17 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu
i++; /* dont return the quote */
while (s[i] != '\0' && out != smax)
{
- if (s[i] == qc && !in_escape)
- break;
#ifdef MULTIBYTE
- if (multibyte_char_check(s[i]) == 0 && s[i] == '\\' && !in_escape)
+ if (multibyte_char_check(s[i]) != 0)
{
-#else
+ token[out++] = s[i++];
+ continue;
+ }
+#endif
+ if (s[i] == qc && !in_escape)
+ break;
if (s[i] == '\\' && !in_escape)
{
-#endif
in_escape = TRUE;
}
else
@@ -269,11 +279,12 @@ parse_statement(StatementClass *stmt)
dquote,
numeric,
unquoted;
- char *ptr;
+ char *ptr, *pptr = NULL;
char in_select = FALSE,
in_distinct = FALSE,
in_on = FALSE,
in_from = FALSE,
+ from_found = FALSE,
in_where = FALSE,
in_table = FALSE;
char in_field = FALSE,
@@ -285,6 +296,7 @@ parse_statement(StatementClass *stmt)
i,
k = 0,
n,
+ first_where = 0,
blevel = 0;
FIELD_INFO **fi;
TABLE_INFO **ti;
@@ -303,59 +315,114 @@ parse_statement(StatementClass *stmt)
stmt->nfld = 0;
stmt->ntab = 0;
- while ((ptr = getNextToken(ptr, token, sizeof(token), &delim, &quote, &dquote, &numeric)) != NULL)
+#ifdef MULTIBYTE
+ multibyte_init();
+#endif
+ while (pptr = ptr, (ptr = getNextToken(pptr, token, sizeof(token), &delim, &quote, &dquote, &numeric)) != NULL)
{
unquoted = !(quote || dquote);
mylog("unquoted=%d, quote=%d, dquote=%d, numeric=%d, delim='%c', token='%s', ptr='%s'\n", unquoted, quote, dquote, numeric, delim, token, ptr);
- if (unquoted && !stricmp(token, "select"))
+ if (in_select && unquoted && blevel == 0)
{
- in_select = TRUE;
-
- mylog("SELECT\n");
- continue;
- }
+ if (!stricmp(token, "distinct"))
+ {
+ in_distinct = TRUE;
- if (unquoted && in_select && !stricmp(token, "distinct"))
- {
- in_distinct = TRUE;
+ mylog("DISTINCT\n");
+ continue;
+ }
+ if (!stricmp(token, "into"))
+ {
+ in_select = FALSE;
+ mylog("INTO\n");
+ stmt->statement_type = STMT_TYPE_CREATE;
+ stmt->parse_status = STMT_PARSE_FATAL;
+ return FALSE;
+ }
+ if (!stricmp(token, "from"))
+ {
+ in_select = FALSE;
+ in_from = TRUE;
+ if (!from_found &&
+ (!strnicmp(pptr, "from", 4)))
+ {
+ mylog("First ");
+ from_found = TRUE;
+ }
- mylog("DISTINCT\n");
- continue;
+ mylog("FROM\n");
+ continue;
+ }
}
-
- if (unquoted && !stricmp(token, "into"))
+ if (unquoted && blevel == 0)
{
- in_select = FALSE;
-
- mylog("INTO\n");
- continue;
+ if ((!stricmp(token, "where") ||
+ !stricmp(token, "union") ||
+ !stricmp(token, "intersect") ||
+ !stricmp(token, "except") ||
+ !stricmp(token, "order") ||
+ !stricmp(token, "group") ||
+ !stricmp(token, "having")))
+ {
+ in_select = FALSE;
+ in_from = FALSE;
+ in_where = TRUE;
+
+ if (!first_where &&
+ (!stricmp(token, "where")))
+ first_where = ptr - stmt->statement;
+
+ mylog("WHERE...\n");
+ break;
+ }
}
-
- if (unquoted && !stricmp(token, "from"))
+ if (in_select && (in_expr || in_func))
{
- in_select = FALSE;
- in_from = TRUE;
+ /* just eat the expression */
+ mylog("in_expr=%d or func=%d\n", in_expr, in_func);
+ if (!unquoted)
+ continue;
- mylog("FROM\n");
+ if (token[0] == '(')
+ {
+ blevel++;
+ mylog("blevel++ = %d\n", blevel);
+ }
+ else if (token[0] == ')')
+ {
+ blevel--;
+ mylog("blevel-- = %d\n", blevel);
+ }
+ if (blevel == 0)
+ {
+ if (delim == ',')
+ {
+ mylog("**** Got comma in_expr/func\n");
+ in_func = FALSE;
+ in_expr = FALSE;
+ in_field = FALSE;
+ }
+ else if (!stricmp(token, "as"))
+ {
+ mylog("got AS in_expr\n");
+ in_func = FALSE;
+ in_expr = FALSE;
+ in_as = TRUE;
+ in_field = TRUE;
+ }
+ }
continue;
}
- if (unquoted && (!stricmp(token, "where") ||
- !stricmp(token, "union") ||
- !stricmp(token, "order") ||
- !stricmp(token, "group") ||
- !stricmp(token, "having")))
+ if (unquoted && !stricmp(token, "select"))
{
- in_select = FALSE;
- in_from = FALSE;
- in_where = TRUE;
+ in_select = TRUE;
- mylog("WHERE...\n");
- break;
+ mylog("SELECT\n");
+ continue;
}
-
if (in_select)
{
if (in_distinct)
@@ -378,41 +445,6 @@ parse_statement(StatementClass *stmt)
in_distinct = FALSE;
}
- if (in_expr || in_func)
- {
- /* just eat the expression */
- mylog("in_expr=%d or func=%d\n", in_expr, in_func);
- if (quote || dquote)
- continue;
-
- if (in_expr && blevel == 0 && delim == ',')
- {
- mylog("**** in_expr and Got comma\n");
- in_expr = FALSE;
- in_field = FALSE;
- }
- else if (token[0] == '(')
- {
- blevel++;
- mylog("blevel++ = %d\n", blevel);
- }
- else if (token[0] == ')')
- {
- blevel--;
- mylog("blevel-- = %d\n", blevel);
- }
- if (blevel == 0)
- {
- if (delim == ',')
- {
- in_func = FALSE;
- in_expr = FALSE;
- in_field = FALSE;
- }
- }
- continue;
- }
-
if (!in_field)
{
if (!token[0])
@@ -447,6 +479,7 @@ parse_statement(StatementClass *stmt)
if (quote)
{
fi[stmt->nfld++]->quote = TRUE;
+in_expr = TRUE;
continue;
}
else if (numeric)
@@ -619,8 +652,12 @@ parse_statement(StatementClass *stmt)
else if (fi[i]->quote)
{ /* handle as text */
fi[i]->ti = NULL;
+ /*
fi[i]->type = PG_TYPE_TEXT;
fi[i]->precision = 0;
+ the following may be better */
+ fi[i]->type = PG_TYPE_UNKNOWN;
+ fi[i]->precision = 254;
continue;
}
/* it's a dot, resolve to table or alias */
@@ -680,12 +717,12 @@ parse_statement(StatementClass *stmt)
if (!found)
{
- mylog("PARSE: Getting SQLColumns for table[%d]='%s'\n", i, ti[i]->name);
+ mylog("PARSE: Getting PG_Columns for table[%d]='%s'\n", i, ti[i]->name);
- result = SQLAllocStmt(stmt->hdbc, &hcol_stmt);
+ result = PGAPI_AllocStmt(stmt->hdbc, &hcol_stmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
- stmt->errormsg = "SQLAllocStmt failed in parse_statement for columns.";
+ stmt->errormsg = "PGAPI_AllocStmt failed in parse_statement for columns.";
stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->parse_status = STMT_PARSE_FATAL;
return FALSE;
@@ -694,10 +731,10 @@ parse_statement(StatementClass *stmt)
col_stmt = (StatementClass *) hcol_stmt;
col_stmt->internal = TRUE;
- result = SQLColumns(hcol_stmt, "", 0, "", 0,
+ result = PGAPI_Columns(hcol_stmt, "", 0, "", 0,
ti[i]->name, (SWORD) strlen(ti[i]->name), "", 0);
- mylog(" Past SQLColumns\n");
+ mylog(" Past PG_Columns\n");
if (result == SQL_SUCCESS)
{
mylog(" Success\n");
@@ -736,12 +773,12 @@ parse_statement(StatementClass *stmt)
conn->ntables++;
- SQLFreeStmt(hcol_stmt, SQL_DROP);
+ PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
mylog("Created col_info table='%s', ntables=%d\n", ti[i]->name, conn->ntables);
}
else
{
- SQLFreeStmt(hcol_stmt, SQL_DROP);
+ PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
break;
}
}
@@ -751,7 +788,7 @@ parse_statement(StatementClass *stmt)
mylog("associate col_info: i=%d, k=%d\n", i, k);
}
- mylog("Done SQLColumns\n");
+ mylog("Done PG_Columns\n");
/*
* Now resolve the fields to point to column info