int main(int argc, char **argv) { List *tree; ListCell *l; if (argc != 2) { fprintf(stderr, "./parser-test query\n"); exit(1); } tree = raw_parser(argv[1]); if (tree == NULL) { printf("syntax error: %s\n", argv[1]); } else { foreach(l, tree) { Node *node = (Node *) lfirst(l); printf("%s\n", nodeToString(node)); } }
bool do_parse(const char* query) { MemoryContext ctx = NULL; List *tree; ctx = AllocSetContextCreate(TopMemoryContext, "RootContext", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); MemoryContextSwitchTo(ctx); tree = raw_parser(query); if (tree != NULL) { char *s; s = nodeToString(tree); printf("%s\n", s); pfree(s); } MemoryContextSwitchTo(TopMemoryContext); MemoryContextDelete(ctx); return (tree != NULL); }
PgQueryNormalizeResult pg_query_normalize(const char* input) { MemoryContext ctx = NULL; PgQueryNormalizeResult result = {0}; ctx = pg_query_enter_memory_context("pg_query_normalize"); PG_TRY(); { List *tree; pgssConstLocations jstate; int query_len; /* Parse query */ tree = raw_parser(input); /* Set up workspace for constant recording */ jstate.clocations_buf_size = 32; jstate.clocations = (pgssLocationLen *) palloc(jstate.clocations_buf_size * sizeof(pgssLocationLen)); jstate.clocations_count = 0; jstate.highest_extern_param_id = 0; /* Walk tree and record const locations */ const_record_walker((Node *) tree, &jstate); /* Normalize query */ query_len = (int) strlen(input); result.normalized_query = strdup(generate_normalized_query(&jstate, input, 0, &query_len, PG_UTF8)); } PG_CATCH(); { ErrorData* error_data; PgQueryError* error; MemoryContextSwitchTo(ctx); error_data = CopyErrorData(); error = malloc(sizeof(PgQueryError)); error->message = strdup(error_data->message); error->filename = strdup(error_data->filename); error->lineno = error_data->lineno; error->cursorpos = error_data->cursorpos; result.error = error; FlushErrorState(); } PG_END_TRY(); pg_query_exit_memory_context(ctx); return result; }
int main(int argc, char **argv) { char *query; List *tree; ListCell *l; StartupPacket sp; POOL_CONNECTION_POOL backend; POOL_CONNECTION_POOL_SLOT slot; POOL_SENT_MESSAGE msg; POOL_QUERY_CONTEXT ctx; backend.slots[0] = &slot; slot.sp = &sp; bool error; MemoryContextInit(); pool_config->replication_mode = 1; if (argc != 2) { fprintf(stderr, "./timestmp-test query\n"); exit(1); } tree = raw_parser(argv[1], &error); if (tree == NULL) { printf("syntax error: %s\n", argv[1]); } else { foreach(l, tree) { msg.num_tsparams = 0; msg.query_context = &ctx; Node *node = (Node *) lfirst(l); query = rewrite_timestamp(&backend, ((RawStmt *) node)->stmt, false, &msg); if (query) printf("%s\n", query); else printf("%s\n", argv[1]); } }
int main(int argc, char **argv) { char *query; List *tree; ListCell *l; Portal portal; POOL_CONNECTION_POOL backend; POOL_CONNECTION_POOL_SLOT slot; backend.slots[0] = &slot; pool_config->replication_mode = 1; if (argc != 2) { fprintf(stderr, "./timestmp-test query\n"); exit(1); } tree = raw_parser(argv[1]); if (tree == NULL) { printf("syntax error: %s\n", argv[1]); } else { foreach(l, tree) { portal.num_tsparams = 0; Node *node = (Node *) lfirst(l); query = rewrite_timestamp(&backend, node, false, &portal); if (query) printf("%s\n", query); else printf("%s\n", argv[1]); } }
PgQueryInternalParsetreeAndError pg_query_raw_parse(const char* input) { PgQueryInternalParsetreeAndError result = {0}; MemoryContext parse_context = CurrentMemoryContext; char stderr_buffer[STDERR_BUFFER_LEN + 1] = {0}; #ifndef DEBUG int stderr_global; int stderr_pipe[2]; #endif #ifndef DEBUG // Setup pipe for stderr redirection if (pipe(stderr_pipe) != 0) { PgQueryError* error = malloc(sizeof(PgQueryError)); error->message = strdup("Failed to open pipe, too many open file descriptors") result.error = error; return result; } fcntl(stderr_pipe[0], F_SETFL, fcntl(stderr_pipe[0], F_GETFL) | O_NONBLOCK); // Redirect stderr to the pipe stderr_global = dup(STDERR_FILENO); dup2(stderr_pipe[1], STDERR_FILENO); close(stderr_pipe[1]); #endif PG_TRY(); { result.tree = raw_parser(input); #ifndef DEBUG // Save stderr for result read(stderr_pipe[0], stderr_buffer, STDERR_BUFFER_LEN); #endif result.stderr_buffer = strdup(stderr_buffer); } PG_CATCH(); { ErrorData* error_data; PgQueryError* error; MemoryContextSwitchTo(parse_context); error_data = CopyErrorData(); // Note: This is intentionally malloc so exiting the memory context doesn't free this error = (PgQueryError *)malloc(sizeof(PgQueryError)); error->message = strdup(error_data->message); error->filename = strdup(error_data->filename); error->lineno = error_data->lineno; error->cursorpos = error_data->cursorpos; result.error = error; FlushErrorState(); } PG_END_TRY(); #ifndef DEBUG // Restore stderr, close pipe dup2(stderr_global, STDERR_FILENO); close(stderr_pipe[0]); close(stderr_global); #endif return result; }
Datum pgsynck(PG_FUNCTION_ARGS) { /* List *raw_parsetree_list = NULL; */ char *query_string = NULL; char *oneq = NULL; char *q; ErrorData *edata = NULL; MemoryContext oldcontext = CurrentMemoryContext; MemoryContext per_query_ctx; ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; TupleDesc tupdesc; Tuplestorestate *tupstore; /* check to see if caller supports us returning a tuplestore */ if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("set-valued function called in context that cannot accept a set"))); if (!(rsinfo->allowedModes & SFRM_Materialize)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("materialize mode required, but it is not " \ "allowed in this context"))); /* Build a tuple descriptor for our result type */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); per_query_ctx = rsinfo->econtext->ecxt_per_query_memory; oldcontext = MemoryContextSwitchTo(per_query_ctx); tupstore = tuplestore_begin_heap(true, false, work_mem); rsinfo->returnMode = SFRM_Materialize; rsinfo->setResult = tupstore; rsinfo->setDesc = tupdesc; MemoryContextSwitchTo(oldcontext); q = query_string = text_to_cstring(PG_GETARG_TEXT_PP(0)); oneq = get_one_query(&q); while (oneq != NULL) { int j = 0; Datum values[PGSYNCK_COLS]; bool nulls[PGSYNCK_COLS]; memset(values, 0, sizeof(values)); memset(nulls, 0, sizeof(nulls)); /* sql */ values[j++] = CStringGetTextDatum(oneq); PG_TRY(); { raw_parser(oneq); /* cursorpos */ values[j++] = Int32GetDatum(0); /* sqlerrcode */ values[j++] = Int32GetDatum(0); /* message - primary error message */ values[j++] = CStringGetTextDatum(""); /* hint - hint message */ values[j++] = CStringGetTextDatum(""); tuplestore_putvalues(tupstore, tupdesc, values, nulls); } PG_CATCH(); { /* Save error info */ MemoryContextSwitchTo(oldcontext); edata = CopyErrorData(); FlushErrorState(); /* cursorpos - cursor index into query string */ values[j++] = Int32GetDatum(edata->cursorpos); /* sqlerrcode - encoded ERRSTATE */ values[j++] = Int32GetDatum(edata->sqlerrcode); /* message - primary error message */ values[j++] = CStringGetTextDatum(edata->message ? edata->message:""); /* hint - hint message */ values[j++] = CStringGetTextDatum(edata->hint ? edata->hint:""); tuplestore_putvalues(tupstore, tupdesc, values, nulls); FreeErrorData(edata); } PG_END_TRY(); oneq = get_one_query(&q); } /* clean up and return the tuplestore */ tuplestore_donestoring(tupstore); return (Datum) 0; }