aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/odbc/parse.c
diff options
context:
space:
mode:
authorHiroshi Inoue <inoue@tpf.co.jp>2002-03-28 08:08:07 +0000
committerHiroshi Inoue <inoue@tpf.co.jp>2002-03-28 08:08:07 +0000
commit6852741c1879fd2bd5ab5b367c7fc5a130dfd4da (patch)
treea0f27a6fb623307b0772f2964f31707fd302972e /src/interfaces/odbc/parse.c
parente6774dc3553d814e6aa500cabe5739b2e6f94df4 (diff)
downloadpostgresql-6852741c1879fd2bd5ab5b367c7fc5a130dfd4da.tar.gz
postgresql-6852741c1879fd2bd5ab5b367c7fc5a130dfd4da.zip
[2002-03-28]
1) Prepare to separate 4 kinds of Descriptor handles. 2) Detect the transaction status more naturally. 3) Improve Parse Statement functionality for the use of updatable cursors. 4) Improve updatable cursors. 5) Implement SQLGetDescField() and improve SQLColAttribute(). 6) etc.
Diffstat (limited to 'src/interfaces/odbc/parse.c')
-rw-r--r--src/interfaces/odbc/parse.c157
1 files changed, 86 insertions, 71 deletions
diff --git a/src/interfaces/odbc/parse.c b/src/interfaces/odbc/parse.c
index 8a7e6d7415c..3549ff2ef7a 100644
--- a/src/interfaces/odbc/parse.c
+++ b/src/interfaces/odbc/parse.c
@@ -236,19 +236,25 @@ void
getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k)
{
char *str;
+ Int2 reserved_cols;
+#if (ODBCVER >= 0x0300)
+ reserved_cols = 18;
+#else
+ reserved_cols = 12;
+#endif /* ODBCVER */
if (fi->name[0] == '\0')
strcpy(fi->name, QR_get_value_manual(col_info->result, k, 3));
- fi->type = atoi(QR_get_value_manual(col_info->result, k, 13));
- fi->precision = atoi(QR_get_value_manual(col_info->result, k, 6));
+ fi->type = atoi(QR_get_value_manual(col_info->result, k, (Int2)(reserved_cols + 1)));
+ fi->column_size = atoi(QR_get_value_manual(col_info->result, k, 6));
fi->length = atoi(QR_get_value_manual(col_info->result, k, 7));
if (str = QR_get_value_manual(col_info->result, k, 8), str)
- fi->scale = atoi(str);
+ fi->decimal_digits = atoi(str);
else
- fi->scale = -1;
+ fi->decimal_digits = -1;
fi->nullable = atoi(QR_get_value_manual(col_info->result, k, 10));
- fi->display_size = atoi(QR_get_value_manual(col_info->result, k, 12));
+ fi->display_size = atoi(QR_get_value_manual(col_info->result, k, reserved_cols));
}
@@ -315,16 +321,17 @@ parse_statement(StatementClass *stmt)
ConnectionClass *conn = stmt->hdbc;
HSTMT hcol_stmt;
StatementClass *col_stmt;
+ IRDFields *irdflds = SC_get_IRD(stmt);
RETCODE result;
BOOL updatable = TRUE;
mylog("%s: entering...\n", func);
ptr = stmt->statement;
- fi = stmt->fi;
+ fi = irdflds->fi;
ti = stmt->ti;
- stmt->nfld = 0;
+ irdflds->nfields = 0;
stmt->ntab = 0;
stmt->from_pos = -1;
stmt->where_pos = -1;
@@ -371,7 +378,7 @@ parse_statement(StatementClass *stmt)
mylog("FROM\n");
continue;
}
- }
+ } /* in_select && unquoted && blevel == 0 */
if (unquoted && blevel == 0)
{
if ((!stricmp(token, "where") ||
@@ -386,18 +393,18 @@ parse_statement(StatementClass *stmt)
in_from = FALSE;
in_where = TRUE;
- if (!stricmp(token, "where"))
+ if (stmt->where_pos < 0)
+ stmt->where_pos = pptr - stmt->statement;
+ mylog("%s...\n", token);
+ if (stricmp(token, "where") &&
+ stricmp(token, "order"))
{
- if (stmt->where_pos < 0)
- stmt->where_pos = pptr - stmt->statement;
- }
- else if (stricmp(token, "order"))
updatable = FALSE;
-
- mylog("WHERE...\n");
- break;
+ break;
+ }
+ continue;
}
- }
+ } /* unquoted && blevel == 0 */
if (in_select && (in_expr || in_func))
{
/* just eat the expression */
@@ -435,7 +442,7 @@ parse_statement(StatementClass *stmt)
}
}
continue;
- }
+ } /* in_select && (in_expr || in_func) */
if (unquoted && !stricmp(token, "select"))
{
@@ -464,81 +471,81 @@ parse_statement(StatementClass *stmt)
}
mylog("done distinct\n");
in_distinct = FALSE;
- }
+ } /* in_distinct */
if (!in_field)
{
if (!token[0])
continue;
- if (!(stmt->nfld % FLD_INCR))
+ if (!(irdflds->nfields % FLD_INCR))
{
- mylog("reallocing at nfld=%d\n", stmt->nfld);
- fi = (FIELD_INFO **) realloc(fi, (stmt->nfld + FLD_INCR) * sizeof(FIELD_INFO *));
+ mylog("reallocing at nfld=%d\n", irdflds->nfields);
+ fi = (FIELD_INFO **) realloc(fi, (irdflds->nfields + FLD_INCR) * sizeof(FIELD_INFO *));
if (!fi)
{
stmt->parse_status = STMT_PARSE_FATAL;
return FALSE;
}
- stmt->fi = fi;
+ irdflds->fi = fi;
}
- fi[stmt->nfld] = (FIELD_INFO *) malloc(sizeof(FIELD_INFO));
- if (fi[stmt->nfld] == NULL)
+ fi[irdflds->nfields] = (FIELD_INFO *) malloc(sizeof(FIELD_INFO));
+ if (fi[irdflds->nfields] == NULL)
{
stmt->parse_status = STMT_PARSE_FATAL;
return FALSE;
}
/* Initialize the field info */
- memset(fi[stmt->nfld], 0, sizeof(FIELD_INFO));
+ memset(fi[irdflds->nfields], 0, sizeof(FIELD_INFO));
/* double quotes are for qualifiers */
if (dquote)
- fi[stmt->nfld]->dquote = TRUE;
+ fi[irdflds->nfields]->dquote = TRUE;
if (quote)
{
- fi[stmt->nfld]->quote = TRUE;
- fi[stmt->nfld]->precision = strlen(token);
+ fi[irdflds->nfields]->quote = TRUE;
+ fi[irdflds->nfields]->column_size = strlen(token);
}
else if (numeric)
{
- mylog("**** got numeric: nfld = %d\n", stmt->nfld);
- fi[stmt->nfld]->numeric = TRUE;
+ mylog("**** got numeric: nfld = %d\n", irdflds->nfields);
+ fi[irdflds->nfields]->numeric = TRUE;
}
else if (token[0] == '(')
{ /* expression */
mylog("got EXPRESSION\n");
- fi[stmt->nfld++]->expr = TRUE;
+ fi[irdflds->nfields++]->expr = TRUE;
in_expr = TRUE;
blevel = 1;
continue;
}
else
{
- strcpy(fi[stmt->nfld]->name, token);
- fi[stmt->nfld]->dot[0] = '\0';
+ strcpy(fi[irdflds->nfields]->name, token);
+ fi[irdflds->nfields]->dot[0] = '\0';
}
- mylog("got field='%s', dot='%s'\n", fi[stmt->nfld]->name, fi[stmt->nfld]->dot);
+ mylog("got field='%s', dot='%s'\n", fi[irdflds->nfields]->name, fi[irdflds->nfields]->dot);
if (delim == ',')
mylog("comma (1)\n");
else
in_field = TRUE;
- stmt->nfld++;
+ irdflds->nfields++;
continue;
- }
+ } /* !in_field */
/*
* We are in a field now
*/
if (in_dot)
{
- stmt->nfld--;
- strcpy(fi[stmt->nfld]->dot, fi[stmt->nfld]->name);
- strcpy(fi[stmt->nfld]->name, token);
- stmt->nfld++;
+ irdflds->nfields--;
+ strcpy(fi[irdflds->nfields]->dot, fi[irdflds->nfields]->name);
+ strcpy(fi[irdflds->nfields]->name, token);
+ irdflds->nfields++;
in_dot = FALSE;
if (delim == ',')
@@ -551,13 +558,13 @@ parse_statement(StatementClass *stmt)
if (in_as)
{
- stmt->nfld--;
- strcpy(fi[stmt->nfld]->alias, token);
- mylog("alias for field '%s' is '%s'\n", fi[stmt->nfld]->name, fi[stmt->nfld]->alias);
+ irdflds->nfields--;
+ strcpy(fi[irdflds->nfields]->alias, token);
+ mylog("alias for field '%s' is '%s'\n", fi[irdflds->nfields]->name, fi[irdflds->nfields]->alias);
in_as = FALSE;
in_field = FALSE;
- stmt->nfld++;
+ irdflds->nfields++;
if (delim == ',')
mylog("comma(2)\n");
@@ -569,13 +576,13 @@ parse_statement(StatementClass *stmt)
{
in_func = TRUE;
blevel = 1;
- fi[stmt->nfld - 1]->func = TRUE;
+ fi[irdflds->nfields - 1]->func = TRUE;
/*
* name will have the function name -- maybe useful some
* day
*/
- mylog("**** got function = '%s'\n", fi[stmt->nfld - 1]->name);
+ mylog("**** got function = '%s'\n", fi[irdflds->nfields - 1]->name);
continue;
}
@@ -595,11 +602,11 @@ parse_statement(StatementClass *stmt)
/* otherwise, it's probably an expression */
in_expr = TRUE;
- fi[stmt->nfld - 1]->expr = TRUE;
- fi[stmt->nfld - 1]->name[0] = '\0';
- fi[stmt->nfld - 1]->precision = 0;
+ fi[irdflds->nfields - 1]->expr = TRUE;
+ fi[irdflds->nfields - 1]->name[0] = '\0';
+ fi[irdflds->nfields - 1]->column_size = 0;
mylog("*** setting expression\n");
- }
+ } /* in_select end */
if (in_from)
{
@@ -607,6 +614,8 @@ parse_statement(StatementClass *stmt)
{
if (!token[0])
continue;
+ if (token[0] == ';')
+ break;
if (!(stmt->ntab % TAB_INCR))
{
@@ -658,12 +667,17 @@ parse_statement(StatementClass *stmt)
continue;
}
- strcpy(ti[stmt->ntab - 1]->alias, token);
- mylog("alias for table '%s' is '%s'\n", ti[stmt->ntab - 1]->name, ti[stmt->ntab - 1]->alias);
- in_table = FALSE;
- if (delim == ',')
- mylog("more than 1 tables\n");
- }
+ if (token[0] == ';')
+ break;
+ if (stricmp(token, "as"))
+ {
+ strcpy(ti[stmt->ntab - 1]->alias, token);
+ mylog("alias for table '%s' is '%s'\n", ti[stmt->ntab - 1]->name, ti[stmt->ntab - 1]->alias);
+ in_table = FALSE;
+ if (delim == ',')
+ mylog("more than 1 tables\n");
+ }
+ } /* in_from */
}
/*
@@ -673,7 +687,7 @@ parse_statement(StatementClass *stmt)
parse = TRUE;
/* Resolve field names with tables */
- for (i = 0; i < stmt->nfld; i++)
+ for (i = 0; i < (int) irdflds->nfields; i++)
{
if (fi[i]->func || fi[i]->expr || fi[i]->numeric)
{
@@ -687,16 +701,16 @@ parse_statement(StatementClass *stmt)
fi[i]->ti = NULL;
/*
- * fi[i]->type = PG_TYPE_TEXT; fi[i]->precision = 0; the
+ * fi[i]->type = PG_TYPE_TEXT; fi[i]->column_size = 0; the
* following may be better
*/
fi[i]->type = PG_TYPE_UNKNOWN;
- if (fi[i]->precision == 0)
+ if (fi[i]->column_size == 0)
{
fi[i]->type = PG_TYPE_VARCHAR;
- fi[i]->precision = 254;
+ fi[i]->column_size = 254;
}
- fi[i]->length = fi[i]->precision;
+ fi[i]->length = fi[i]->column_size;
continue;
}
/* it's a dot, resolve to table or alias */
@@ -721,9 +735,9 @@ parse_statement(StatementClass *stmt)
}
mylog("--------------------------------------------\n");
- mylog("nfld=%d, ntab=%d\n", stmt->nfld, stmt->ntab);
+ mylog("nfld=%d, ntab=%d\n", irdflds->nfields, stmt->ntab);
- for (i = 0; i < stmt->nfld; i++)
+ for (i = 0; i < (int) irdflds->nfields; i++)
{
mylog("Field %d: expr=%d, func=%d, quote=%d, dquote=%d, numeric=%d, name='%s', alias='%s', dot='%s'\n", i, fi[i]->expr, fi[i]->func, fi[i]->quote, fi[i]->dquote, fi[i]->numeric, fi[i]->name, fi[i]->alias, fi[i]->dot);
if (fi[i]->ti)
@@ -836,7 +850,7 @@ parse_statement(StatementClass *stmt)
/*
* Now resolve the fields to point to column info
*/
- for (i = 0; i < stmt->nfld;)
+ for (i = 0; i < (int) irdflds->nfields;)
{
fi[i]->updatable = updatable;
/* Dont worry about functions or quotes */
@@ -875,8 +889,8 @@ parse_statement(StatementClass *stmt)
increased_cols = total_cols - 1;
/* Allocate some more field pointers if necessary */
- old_alloc = ((stmt->nfld - 1) / FLD_INCR + 1) * FLD_INCR;
- new_size = stmt->nfld + increased_cols;
+ old_alloc = ((irdflds->nfields - 1) / FLD_INCR + 1) * FLD_INCR;
+ new_size = irdflds->nfields + increased_cols;
mylog("k=%d, increased_cols=%d, old_alloc=%d, new_size=%d\n", k, increased_cols, old_alloc, new_size);
@@ -891,14 +905,14 @@ parse_statement(StatementClass *stmt)
stmt->parse_status = STMT_PARSE_FATAL;
return FALSE;
}
- stmt->fi = fi;
+ irdflds->fi = fi;
}
/*
* copy any other fields (if there are any) up past the
* expansion
*/
- for (j = stmt->nfld - 1; j > i; j--)
+ for (j = irdflds->nfields - 1; j > i; j--)
{
mylog("copying field %d to %d\n", j, increased_cols + j);
fi[increased_cols + j] = fi[j];
@@ -906,8 +920,8 @@ parse_statement(StatementClass *stmt)
mylog("done copying fields\n");
/* Set the new number of fields */
- stmt->nfld += increased_cols;
- mylog("stmt->nfld now at %d\n", stmt->nfld);
+ irdflds->nfields += increased_cols;
+ mylog("irdflds->nfields now at %d\n", irdflds->nfields);
/* copy the new field info */
@@ -990,6 +1004,7 @@ parse_statement(StatementClass *stmt)
else
stmt->parse_status = STMT_PARSE_COMPLETE;
+ stmt->updatable = updatable;
mylog("done parse_statement: parse=%d, parse_status=%d\n", parse, stmt->parse_status);
return parse;
}