** Lua stack: ** 1: Lua str (tmptbl name) ** 2: Lua tbl (tmptbl schema) */
| 1155 | ** 2: Lua tbl (tmptbl schema) |
| 1156 | */ |
| 1157 | static int create_temp_table(Lua lua, pthread_mutex_t **lk, const char **name) |
| 1158 | { |
| 1159 | int rc = -1; |
| 1160 | strbuf *sql = NULL; |
| 1161 | SP sp = getsp(lua); |
| 1162 | char n1[MAXTABLELEN], n2[MAXTABLELEN]; |
| 1163 | *name = lua_tostring(lua, 1); |
| 1164 | if (two_part_tbl_name(*name, n1, n2) != 0) { |
| 1165 | luabb_error(lua, sp, "bad table name:%s", *name); |
| 1166 | goto out; |
| 1167 | } |
| 1168 | if (strcasecmp(n1, "") != 0 && strcasecmp(n1, "temp") != 0) { |
| 1169 | luabb_error(lua, sp, "bad table name:%s", *name); |
| 1170 | goto out; |
| 1171 | } |
| 1172 | sql = strbuf_new(); |
| 1173 | strbuf_appendf(sql, "CREATE TEMP TABLE \"%s\" (", n2); |
| 1174 | size_t num = lua_objlen(lua, 2); |
| 1175 | const char *comma = ""; |
| 1176 | for (size_t i = 1; i <= num; ++i) { |
| 1177 | lua_rawgeti(lua, 2, i); |
| 1178 | if (!lua_istable(lua, -1)) { |
| 1179 | luabb_error(lua, sp, "bad argument (columns) to 'table'"); |
| 1180 | goto out; |
| 1181 | } |
| 1182 | if (lua_objlen(lua, -1) != 2) { // need {"name", "type"} |
| 1183 | luabb_error(lua, sp, "bad argument (columns) to 'table'"); |
| 1184 | goto out; |
| 1185 | } |
| 1186 | lua_rawgeti(lua, -1, 1); |
| 1187 | lua_rawgeti(lua, -2, 2); |
| 1188 | char *quoted_col = sqlite3_mprintf("\"%w\"", lua_tostring(lua, -2)); |
| 1189 | strbuf_appendf(sql, "%s%s %s", comma, quoted_col, |
| 1190 | lua_tostring(lua, -1)); |
| 1191 | sqlite3_free(quoted_col); |
| 1192 | lua_pop(lua, 3); |
| 1193 | comma = ", "; |
| 1194 | } |
| 1195 | strbuf_append(sql, ")"); |
| 1196 | |
| 1197 | // Following can throw exception which may leak strbuf. |
| 1198 | // Copy DDL string onto stack instead. |
| 1199 | int len = strbuf_len(sql) + 1; |
| 1200 | char *ddl = alloca(len); |
| 1201 | memcpy(ddl, strbuf_buf(sql), len); |
| 1202 | strbuf_free(sql); |
| 1203 | sql = NULL; |
| 1204 | sqlite3_stmt *stmt; |
| 1205 | if ((rc = lua_prepare_sql_with_temp_ddl(sp, ddl, &stmt)) != 0) { |
| 1206 | goto out; |
| 1207 | } |
| 1208 | |
| 1209 | *lk = malloc(sizeof(pthread_mutex_t)); |
| 1210 | Pthread_mutex_init(*lk, NULL); |
| 1211 | comdb2_set_tmptbl_lk(*lk); |
| 1212 | lua_begin_step(sp->clnt, sp, stmt); |
| 1213 | while ((rc = sqlite3_maybe_step(sp->clnt, stmt)) == SQLITE_ROW) { |
| 1214 | lua_another_step(sp->clnt, stmt, rc); |
no test coverage detected