static bool const_record_walker(Node *node, pgssConstLocations *jstate)
{
	bool result;

	if (node == NULL) return false;

	if ((IsA(node, A_Const) && ((A_Const *) node)->location >= 0) || (IsA(node, DefElem) && ((DefElem *) node)->location >= 0))
	{
		/* enlarge array if needed */
		if (jstate->clocations_count >= jstate->clocations_buf_size)
		{
			jstate->clocations_buf_size *= 2;
			jstate->clocations = (pgssLocationLen *)
				repalloc(jstate->clocations,
						 jstate->clocations_buf_size *
						 sizeof(pgssLocationLen));
		}
		jstate->clocations[jstate->clocations_count].location = IsA(node, DefElem) ? ((DefElem *) node)->location : ((A_Const *) node)->location;
		/* initialize lengths to -1 to simplify fill_in_constant_lengths */
		jstate->clocations[jstate->clocations_count].length = -1;
		jstate->clocations_count++;
	}
	else if (IsA(node, VariableSetStmt))
	{
		return const_record_walker((Node *) ((VariableSetStmt *) node)->args, jstate);
	}
	else if (IsA(node, CopyStmt))
	{
		return const_record_walker((Node *) ((CopyStmt *) node)->query, jstate);
	}
	else if (IsA(node, ExplainStmt))
	{
		return const_record_walker((Node *) ((ExplainStmt *) node)->query, jstate);
	}
	else if (IsA(node, AlterRoleStmt))
	{
		return const_record_walker((Node *) ((AlterRoleStmt *) node)->options, jstate);
	}

	PG_TRY();
	{
		result = raw_expression_tree_walker(node, const_record_walker, (void*) jstate);
	}
	PG_CATCH();
	{
		FlushErrorState();
		result = false;
	}
	PG_END_TRY();

	return result;
}
示例#2
0
static bool const_record_walker(Node *node, pgssConstLocations *jstate)
{
	bool result;

	if (node == NULL) return false;

	if (IsA(node, A_Const))
	{
		RecordConstLocation(jstate, castNode(A_Const, node)->location);
	}
	else if (IsA(node, ParamRef))
	{
		/* Track the highest ParamRef number */
		if (((ParamRef *) node)->number > jstate->highest_extern_param_id)
			jstate->highest_extern_param_id = castNode(ParamRef, node)->number;
	}
	else if (IsA(node, DefElem))
	{
		return const_record_walker((Node *) ((DefElem *) node)->arg, jstate);
	}
	else if (IsA(node, RawStmt))
	{
		return const_record_walker((Node *) ((RawStmt *) node)->stmt, jstate);
	}
	else if (IsA(node, VariableSetStmt))
	{
		return const_record_walker((Node *) ((VariableSetStmt *) node)->args, jstate);
	}
	else if (IsA(node, CopyStmt))
	{
		return const_record_walker((Node *) ((CopyStmt *) node)->query, jstate);
	}
	else if (IsA(node, ExplainStmt))
	{
		return const_record_walker((Node *) ((ExplainStmt *) node)->query, jstate);
	}
	else if (IsA(node, AlterRoleStmt))
	{
		return const_record_walker((Node *) ((AlterRoleStmt *) node)->options, jstate);
	}
	else if (IsA(node, DeclareCursorStmt))
	{
		return const_record_walker((Node *) ((DeclareCursorStmt *) node)->query, jstate);
	}

	PG_TRY();
	{
		result = raw_expression_tree_walker(node, const_record_walker, (void*) jstate);
	}
	PG_CATCH();
	{
		FlushErrorState();
		result = false;
	}
	PG_END_TRY();

	return result;
}
示例#3
0
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;
}