📄 parse.c
字号:
/**************************/ /* 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++; in_dot = FALSE; if (delim == ',') { mylog("in_dot: got comma\n"); in_field = FALSE; } continue; } 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); in_as = FALSE; in_field = FALSE; stmt->nfld++; if (delim == ',') { mylog("comma(2)\n"); } continue; } /* Function */ if (token[0] == '(') { in_func = TRUE; blevel = 1; fi[stmt->nfld-1]->func = TRUE; /* name will have the function name -- maybe useful some day */ mylog("**** got function = '%s'\n", fi[stmt->nfld-1]->name); continue; } if (token[0] == '.') { in_dot = TRUE; mylog("got dot\n"); continue; } if ( ! stricmp(token, "as")) { in_as = TRUE; mylog("got AS\n"); continue; } /* otherwise, its probably an expression */ in_expr = TRUE; fi[stmt->nfld-1]->expr = TRUE; fi[stmt->nfld-1]->name[0] = '\0'; mylog("*** setting expression\n"); } if (in_from) { if ( ! in_table) { if ( ! token[0]) continue; if ( ! (stmt->ntab % TAB_INCR)) { ti = (TABLE_INFO **) realloc(ti, (stmt->ntab + TAB_INCR) * sizeof(TABLE_INFO *)); if ( ! ti) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } stmt->ti = ti; } ti[stmt->ntab] = (TABLE_INFO *) malloc(sizeof(TABLE_INFO)); if (ti[stmt->ntab] == NULL) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } ti[stmt->ntab]->alias[0] = '\0'; strcpy(ti[stmt->ntab]->name, token); mylog("got table = '%s'\n", ti[stmt->ntab]->name); if (delim == ',') { mylog("more than 1 tables\n"); } else { in_table = TRUE; } stmt->ntab++; 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"); } } } /*************************************************/ /* Resolve any possible field names with tables */ /*************************************************/ parse = TRUE; /* Resolve field names with tables */ for (i = 0; i < stmt->nfld; i++) { if (fi[i]->func || fi[i]->expr || fi[i]->numeric) { fi[i]->ti = NULL; fi[i]->type = -1; parse = FALSE; continue; } else if (fi[i]->quote) { /* handle as text */ fi[i]->ti = NULL; fi[i]->type = PG_TYPE_TEXT; fi[i]->precision = 0; continue; } /* its a dot, resolve to table or alias */ else if (fi[i]->dot[0]) { for (k = 0; k < stmt->ntab; k++) { if ( ! stricmp(ti[k]->name, fi[i]->dot)) { fi[i]->ti = ti[k]; break; } else if ( ! stricmp(ti[k]->alias, fi[i]->dot)) { fi[i]->ti = ti[k]; break; } } } else if (stmt->ntab == 1) fi[i]->ti = ti[0]; } mylog("--------------------------------------------\n"); mylog("nfld=%d, ntab=%d\n", stmt->nfld, stmt->ntab); for (i=0; i < stmt->nfld; 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) mylog(" ----> table_name='%s', table_alias='%s'\n", fi[i]->ti->name, fi[i]->ti->alias); } for (i=0; i < stmt->ntab; i++) { mylog("Table %d: name='%s', alias='%s'\n", i, ti[i]->name, ti[i]->alias); } /******************************************************/ /* Now save the SQLColumns Info for the parse tables */ /******************************************************/ /* Call SQLColumns for each table and store the result */ for (i = 0; i < stmt->ntab; i++) { /* See if already got it */ char found = FALSE; for (k = 0; k < conn->ntables; k++) { if ( ! stricmp(conn->col_info[k]->name, ti[i]->name)) { mylog("FOUND col_info table='%s'\n", ti[i]->name); found = TRUE; break; } } if ( ! found) { mylog("PARSE: Getting SQLColumns for table[%d]='%s'\n", i, ti[i]->name); result = SQLAllocStmt( stmt->hdbc, &hcol_stmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = "SQLAllocStmt failed in parse_statement for columns."; stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } col_stmt = (StatementClass *) hcol_stmt; col_stmt->internal = TRUE; result = SQLColumns(hcol_stmt, "", 0, "", 0, ti[i]->name, (SWORD) strlen(ti[i]->name), "", 0); mylog(" Past SQLColumns\n"); if (result == SQL_SUCCESS) { mylog(" Success\n"); if ( ! (conn->ntables % COL_INCR)) { mylog("PARSE: Allocing col_info at ntables=%d\n", conn->ntables); conn->col_info = (COL_INFO **) realloc(conn->col_info, (conn->ntables + COL_INCR) * sizeof(COL_INFO *)); if ( ! conn->col_info) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } } mylog("PARSE: malloc at conn->col_info[%d]\n", conn->ntables); conn->col_info[conn->ntables] = (COL_INFO *) malloc(sizeof(COL_INFO)); if ( ! conn->col_info[conn->ntables]) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } /* Store the table name and the SQLColumns result structure */ strcpy(conn->col_info[conn->ntables]->name, ti[i]->name); conn->col_info[conn->ntables]->result = col_stmt->result; /* The connection will now free the result structures, so make sure that the statement doesn't free it */ col_stmt->result = NULL; conn->ntables++; SQLFreeStmt(hcol_stmt, SQL_DROP); mylog("Created col_info table='%s', ntables=%d\n", ti[i]->name, conn->ntables); } else { SQLFreeStmt(hcol_stmt, SQL_DROP); break; } } /* Associate a table from the statement with a SQLColumn info */ ti[i]->col_info = conn->col_info[k]; mylog("associate col_info: i=%d, k=%d\n", i, k); } mylog("Done SQLColumns\n"); /******************************************************/ /* Now resolve the fields to point to column info */ /******************************************************/ for (i = 0; i < stmt->nfld;) { /* Dont worry about functions or quotes */ if (fi[i]->func || fi[i]->quote || fi[i]->numeric) { i++; continue; } /* Stars get expanded to all fields in the table */ else if (fi[i]->name[0] == '*') { char do_all_tables; int total_cols, old_size, need, cols; mylog("expanding field %d\n", i); total_cols = 0; if (fi[i]->ti) /* The star represents only the qualified table */ total_cols = QR_get_num_tuples(fi[i]->ti->col_info->result); else { /* The star represents all tables */ /* Calculate the total number of columns after expansion */ for (k = 0; k < stmt->ntab; k++) { total_cols += QR_get_num_tuples(ti[k]->col_info->result); } } total_cols--; /* makes up for the star */ /* Allocate some more field pointers if necessary */ //------------------------------------------------------------- old_size = (stmt->nfld / FLD_INCR * FLD_INCR + FLD_INCR); need = total_cols - (old_size - stmt->nfld); mylog("k=%d, total_cols=%d, old_size=%d, need=%d\n", k,total_cols,old_size,need); if (need > 0) { int new_size = need / FLD_INCR * FLD_INCR + FLD_INCR; mylog("need more cols: new_size = %d\n", new_size); fi = (FIELD_INFO **) realloc(fi, (old_size + new_size) * sizeof(FIELD_INFO *)); if ( ! fi) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } } //------------------------------------------------------------- // copy any other fields (if there are any) up past the expansion for (j = stmt->nfld - 1; j > i; j--) { mylog("copying field %d to %d\n", j, total_cols + j); fi[total_cols + j] = fi[j]; } mylog("done copying fields\n"); //------------------------------------------------------------- // Set the new number of fields stmt->nfld += total_cols; mylog("stmt->nfld now at %d\n", stmt->nfld); //------------------------------------------------------------- // copy the new field info do_all_tables = (fi[i]->ti ? FALSE : TRUE); for (k = 0; k < (do_all_tables ? stmt->ntab : 1); k++) { TABLE_INFO *the_ti = do_all_tables ? ti[k] : fi[i]->ti; cols = QR_get_num_tuples(the_ti->col_info->result); for (n = 0; n < cols; n++) { mylog("creating field info: n=%d\n", n); // skip malloc (already did it for the Star) if (k > 0 || n > 0) { mylog("allocating field info at %d\n", n + i); fi[n + i] = (FIELD_INFO *) malloc( sizeof(FIELD_INFO)); if (fi[n + i] == NULL) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } } /* Initialize the new space (or the * field) */ memset(fi[n + i], 0, sizeof(FIELD_INFO)); fi[n + i]->ti = the_ti; mylog("about to copy at %d\n", n + i); getColInfo(the_ti->col_info, fi[n + i], n); mylog("done copying\n"); } i += cols; mylog("i now at %d\n", i); } //------------------------------------------------------------- } /* We either know which table the field was in because it was qualified with a table name or alias -OR- there was only 1 table. */ else if (fi[i]->ti) { if ( ! searchColInfo(fi[i]->ti->col_info, fi[i])) parse = FALSE; i++; } /* Don't know the table -- search all tables in "from" list */ else { parse = FALSE; for (k = 0; k < stmt->ntab; k++) { if ( searchColInfo(ti[k]->col_info, fi[i])) { fi[i]->ti = ti[k]; /* now know the table */ parse = TRUE; break; } } i++; } } if ( ! parse) stmt->parse_status = STMT_PARSE_INCOMPLETE; else stmt->parse_status = STMT_PARSE_COMPLETE; mylog("done parse_statement: parse=%d, parse_status=%d\n", parse, stmt->parse_status); return parse;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -